diff --git a/src/lisp/e_asin.c b/src/lisp/e_asin.c index af945fec32a41686853e57edf885a1a5736c2319..183ef6d300752435691cf464dd3544272e3d0de6 100644 --- a/src/lisp/e_asin.c +++ b/src/lisp/e_asin.c @@ -89,7 +89,12 @@ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ return fdlibm_setexception(x, FDLIBM_INVALID); } else if (ix<0x3fe00000) { /* |x|<0.5 */ if(ix<0x3e400000) { /* if |x| < 2**-27 */ - if(huge+x>one) return x;/* return x with inexact if x!=0*/ + /* return x inexact except 0 */ + if (x != 0) { + fdlibm_setexception(x, FDLIBM_INEXACT); + } + + return x; } else t = x*x; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); diff --git a/tests/fdlibm.lisp b/tests/fdlibm.lisp index 43ef72570972b93f287d7f92357707dc29c0b9ef..e78cdc58499920606bda139fa47b5dd6a9bb3d50 100644 --- a/tests/fdlibm.lisp +++ b/tests/fdlibm.lisp @@ -556,4 +556,21 @@ (assert-eql -1d0 (tanh -100d0)) ;; tanh(1d300), no overflow (assert-eql 1d0 (tanh most-positive-double-float)) - (assert-eql -1d0 (tanh (- most-positive-double-float)))) \ No newline at end of file + (assert-eql -1d0 (tanh (- most-positive-double-float)))) + +(define-test asin-basic-tests + (:tag :fdlibm) + (let ((x (scale-float 1d0 -28)) + (x0 0d0)) + ;; asin(x) = x for |x| < 2^-27, with inexact exception if x is not 0. + (assert-eql x (asin x)) + (assert-eql (- x) (asin (- x))) + (with-inexact-exception-enabled + ;; This must not throw an inexact exception because the result + ;; is exact when the arg is 0. + (assert-eql 0d0 (asin 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 + (asin x)))))