From d448ca78228ea8b9173a4b42d24d16c8e9a4ef55 Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Wed, 23 Dec 2015 19:49:21 -0800
Subject: [PATCH] Use setexception to raise the inexact exception for cos.

---
 src/lisp/k_cos.c  |  7 ++++++-
 tests/fdlibm.lisp | 14 ++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/lisp/k_cos.c b/src/lisp/k_cos.c
index 2be76e07e..e3af8aa35 100644
--- a/src/lisp/k_cos.c
+++ b/src/lisp/k_cos.c
@@ -75,7 +75,12 @@ C6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
         ux.d = x;
 	ix = ux.i[HIWORD]&0x7fffffff;	/* ix = |x|'s high word*/
 	if(ix<0x3e400000) {			/* if x < 2**27 */
-	    if(((int)x)==0) return one;		/* generate inexact */
+            /* return 1 with inexact unless x == 0 */
+            if (x != 0) {
+                fdlibm_setexception(x, FDLIBM_INEXACT);
+            }
+
+            return one;
 	}
 	z  = x*x;
 	r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
diff --git a/tests/fdlibm.lisp b/tests/fdlibm.lisp
index 9ca9d3001..b99141e65 100644
--- a/tests/fdlibm.lisp
+++ b/tests/fdlibm.lisp
@@ -608,3 +608,17 @@
 	(assert-error 'floating-point-inexact
 		      (kernel:%asin x)))))
 
+(define-test %cos.exceptions
+    (:tag :fdlibm)
+  ;; cos(x) = 1 for |x| < 2^-27.  Signal inexact unless x = 0
+  (let ((x (scale-float 1d0 -28))
+	(x0 0d0))
+    (with-inexact-exception-enabled
+	;; This must not throw an inexact exception because the result
+	;; is exact when the arg is 0.
+	(assert-eql 1d0 (kernel:%cos x0)))
+    (with-inexact-exception-enabled
+	;; This must throw an inexact exception for non-zero x even
+	;; though the result is exactly x.
+	(assert-error 'floating-point-inexact
+		      (kernel:%cos x)))))
-- 
GitLab