From 9a24378eb98d01c3a76285029dd07fc3de4417f8 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <campbell@mumble.net>
Date: Tue, 20 Aug 2019 02:51:27 +0000
Subject: [PATCH] Expand edge cases for ANGLE.

Based on Kahan's `Much Ado about Nothing's Sign Bit' paper.  We screw
up some zero edge cases.
---
 tests/runtime/test-arith.scm | 63 ++++++++++++++++++++++++++++++------
 1 file changed, 54 insertions(+), 9 deletions(-)

diff --git a/tests/runtime/test-arith.scm b/tests/runtime/test-arith.scm
index 8629177af..2af91e595 100644
--- a/tests/runtime/test-arith.scm
+++ b/tests/runtime/test-arith.scm
@@ -735,24 +735,69 @@ USA.
   (lambda (z)
     (assert-inf+ (magnitude z))))
 
-(define-enumerated-test 'infinite-angle
+(define-enumerated-test 'angle-edge
   (list
+   ;; angle(+0 +/- 0i) = +/-0
+   (list 0 0)
+   (list 0. 0.)
+   (list +0.i 0.)
+   (list -0.i -0. expect-failure)
+   (list +0.+0.i 0.)
+   (list +0.-0.i -0. expect-failure)
+   ;; angle(+inf +/- y i) = +/- 0 for finite y
    (list +inf.0 0.)   ;XXX Why not exact, if imag-part is exact 0?
-   (list -inf.0 pi)
+   (list +inf.0+0.i 0.)
+   (list +inf.0-0.i -0.)
    (list +inf.0+i 0.)
    (list +inf.0-i -0.)
-   (list -inf.0-i (- pi))
-   (list -inf.0+i pi)
+   ;; angle(+inf +/- inf i) = +/- pi/4
+   (list +inf.0+inf.0i (* pi 1/4))
+   (list +inf.0-inf.0i (* pi -1/4))
+   ;; angle(x +/- inf i) = +/- pi/2
+   (list +inf.0i (* pi 1/2))
+   (list -inf.0i (* pi -1/2))
+   (list +0.+inf.0i (* pi 1/2))
+   (list +0.-inf.0i (* pi -1/2))
+   (list -0.+inf.0i (* pi 1/2))
+   (list -0.-inf.0i (* pi -1/2))
    (list 1+inf.0i (* pi 1/2))
    (list 1-inf.0i (* pi -1/2))
    (list -1-inf.0i (* pi -1/2))
    (list -1+inf.0i (* pi 1/2))
-   (list +inf.0+inf.0i (* pi 1/4))
-   (list +inf.0-inf.0i (* pi -1/4))
+   ;; angle(-inf +/- inf i) = +/- 3pi/4
    (list -inf.0-inf.0i (* pi -3/4))
-   (list -inf.0+inf.0i (* pi 3/4)))
-  (lambda (z t)
-    (assert-<= (relerr t (angle z)) 1e-15)))
+   (list -inf.0+inf.0i (* pi 3/4))
+   ;; angle(-inf +/- y i) = +/- pi for finite y
+   (list -inf.0 pi)
+   (list -inf.0+0.i pi)
+   (list -inf.0-0.i (- pi))
+   (list -inf.0+i pi)
+   (list -inf.0-i (- pi))
+   ;; angle(-0 +/- 0i) = +/- pi
+   (list -0. pi expect-failure)
+   (list -0.+0.i pi expect-failure)
+   (list -0.-0.i (- pi) expect-failure))
+  (lambda (z t #!optional xfail)
+    (with-expected-failure xfail
+      (lambda ()
+	(assert-<= (relerr t (angle z)) 1e-15)))))
+
+(define-enumerated-test 'angle-nan
+  (list
+   (list +nan.0i)
+   (list 1+nan.0i)
+   (list 0.+nan.0i)
+   (list -0.+nan.0i)
+   (list +inf.0+nan.0i)
+   (list -inf.0+nan.0i)
+   (list +nan.0+i)
+   (list +nan.0+0.i)
+   (list +nan.0-0.i)
+   (list +nan.0+inf.0i)
+   (list +nan.0-inf.0i)
+   (list +nan.123+nan.456i))
+  (lambda (z)
+    (assert-nan (no-traps (lambda () (angle z))))))
 
 (define-enumerated-test 'sqrt-exact
   `((0 0)
-- 
2.25.1