diff --git a/src/lisp/k_sin.c b/src/lisp/k_sin.c index dd660af7851b62c6f6da3d5addeb4f204776c040..41ccfa0f11a91b862cdf2547e3f30b25543a935b 100644 --- a/src/lisp/k_sin.c +++ b/src/lisp/k_sin.c @@ -67,8 +67,14 @@ S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ ux.d = x; ix = ux.i[HIWORD]&0x7fffffff; /* high word of x */ - if(ix<0x3e400000) /* |x| < 2**-27 */ - {if((int)x==0) return x;} /* generate inexact */ + if(ix<0x3e400000) { /* |x| < 2**-27 */ + /* return x inexact except 0 */ + if (x != 0) { + fdlibm_setexception(x, FDLIBM_INEXACT); + } + + return x; + } z = x*x; v = z*x; r = S2+z*(S3+z*(S4+z*(S5+z*S6))); diff --git a/tests/fdlibm.lisp b/tests/fdlibm.lisp index b99141e65d7fcedba56a5088ee2e58369b3903b1..a4a0ca76a9f00cade75005686b5bd832391db72b 100644 --- a/tests/fdlibm.lisp +++ b/tests/fdlibm.lisp @@ -622,3 +622,19 @@ ;; though the result is exactly x. (assert-error 'floating-point-inexact (kernel:%cos x))))) + +(define-test %sin.exceptions + (:tag :fdlibm) + ;; sin(x) = x 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 0d0 (kernel:%sin 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:%sin x))))) +