Raymond Toy pushed to branch master at cmucl / cmucl Commits: 9bf28346 by Raymond Toy at 2026-02-18T07:18:07-08:00 Fix #473: Signal underflow with core-math exp - - - - - b26718dd by Raymond Toy at 2026-02-18T07:18:07-08:00 Merge branch 'issue-473-make-cr-exp-signal-underflow' into 'master' Fix #473: Signal underflow with core-math exp Closes #473 See merge request cmucl/cmucl!351 - - - - - 2 changed files: - src/lisp/irrat.c - tests/fdlibm.lisp Changes: ===================================== src/lisp/irrat.c ===================================== @@ -40,7 +40,7 @@ extern void cr_sincos(double, double *, double *); */ #define MAYBE_SIGNAL_INVALID(test, val) \ - if ((test)) { \ + if ((test)) { \ return fdlibm_setexception(val, FDLIBM_INVALID); \ } @@ -197,6 +197,27 @@ double lisp_exp(double x) { #ifdef FEATURE_CORE_MATH + /* + * For consistency, silently return NaN when x is NaN. Do not + * signal an invalid operation, even if invalid operation trap is + * enabled. This is what fdlibm does, and also what many of the + * other core-math routines do. + */ + + if (isnan(x)) { + return x; + } + + /* + * Can't depend on cr_exp to signal underflow. It seems the + * underflow has been constant-folded to zero. Hence, check for + * underflow here and explicitly signal an underflow. The + * constant here is from core-math exp.c. + */ + if (x <= -0x1.74910d52d3052p+9) { + return fdlibm_setexception(0.0, FDLIBM_UNDERFLOW); + } + return cr_exp(x); #else return __ieee754_exp(x); ===================================== tests/fdlibm.lisp ===================================== @@ -210,13 +210,9 @@ (ext:with-float-traps-masked (:overflow) (assert-equal ext:double-float-positive-infinity (kernel:%exp 710d0))) - (let ((modes (ext:get-floating-point-modes))) - (unwind-protect - (progn - (ext:set-floating-point-modes :traps '(:underflow)) - (assert-error 'floating-point-underflow - (kernel:%exp -1000d0))) - (apply #'ext:set-floating-point-modes modes))) + (ext:with-float-traps-enabled (:underflow) + (assert-error 'floating-point-underflow + (kernel:%exp -1000d0))) (let ((x (scale-float 1d0 -29)) (x0 0d0)) ;; exp(x) = x, |x| < 2^-28, with inexact exception unlees x = 0 View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/53a087cadc014ec991da885... -- View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/53a087cadc014ec991da885... You're receiving this email because of your account on gitlab.common-lisp.net.
participants (1)
-
Raymond Toy (@rtoy)