diff --git a/src/lisp/e_exp.c b/src/lisp/e_exp.c index 93b638e669c58a94f447c231088544c9b9cc6e34..3a9ce0fdfc6493e38813a6a58302f001e334f6d1 100644 --- a/src/lisp/e_exp.c +++ b/src/lisp/e_exp.c @@ -161,7 +161,12 @@ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ x = hi - lo; } else if(hx < 0x3e300000) { /* when |x|<2**-28 */ - if(huge+x>one) return one+x;/* trigger inexact */ + /* return x inexact except 0 */ + if (x != 0) { + fdlibm_setexception(x, FDLIBM_INEXACT); + } + + return one + x; } else k = 0; diff --git a/tests/fdlibm.lisp b/tests/fdlibm.lisp index b540e95e59698ac1fff0c71116acfb05a675c9f7..700b64e2ddfd1956ecbfe3cc36628308002b0dc5 100644 --- a/tests/fdlibm.lisp +++ b/tests/fdlibm.lisp @@ -187,7 +187,19 @@ (ext:set-floating-point-modes :traps '(:underflow)) (assert-error 'floating-point-underflow (kernel:%exp -1000d0))) - (apply #'ext:set-floating-point-modes modes)))) + (apply #'ext:set-floating-point-modes modes))) + (let ((x (scale-float 1d0 -29)) + (x0 0d0)) + ;; exp(x) = x, |x| < 2^-28, with inexact exception unlees x = 0 + (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:%exp 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:%exp x))))) (define-test %log.exception (:tag :fdlibm)