Raymond Toy pushed to branch issue-425-correctly-rounded-math-functions-single-float at cmucl / cmucl
Commits:
-
d2210864
by Raymond Toy at 2026-02-16T14:31:08-08:00
-
c84c6c27
by Raymond Toy at 2026-02-16T18:52:48-08:00
-
72096452
by Raymond Toy at 2026-02-17T10:51:19-08:00
-
7fa0f3c1
by Raymond Toy at 2026-02-17T19:59:33-08:00
2 changed files:
Changes:
| ... | ... | @@ -62,7 +62,7 @@ extern void cr_sincosf(float, float *, float *); |
| 62 | 62 | */
|
| 63 | 63 | |
| 64 | 64 | #define MAYBE_SIGNAL_INVALID(test, val) \
|
| 65 | - if ((test)) { \
|
|
| 65 | + if ((test)) { \
|
|
| 66 | 66 | return fdlibm_setexception(val, FDLIBM_INVALID); \
|
| 67 | 67 | }
|
| 68 | 68 | |
| ... | ... | @@ -221,6 +221,27 @@ double |
| 221 | 221 | lisp_exp(double x)
|
| 222 | 222 | {
|
| 223 | 223 | #ifdef FEATURE_CORE_MATH
|
| 224 | + /*
|
|
| 225 | + * For consistency, silently return NaN when x is NaN. Do not
|
|
| 226 | + * signal an invalid operation, even if invalid operation trap is
|
|
| 227 | + * enabled. This is what fdlibm does, and also what many of the
|
|
| 228 | + * other core-math routines do.
|
|
| 229 | + */
|
|
| 230 | + |
|
| 231 | + if (isnan(x)) {
|
|
| 232 | + return x;
|
|
| 233 | + }
|
|
| 234 | +
|
|
| 235 | + /*
|
|
| 236 | + * Can't depend on cr_exp to signal underflow. It seems the
|
|
| 237 | + * underflow has been constant-folded to zero. Hence, check for
|
|
| 238 | + * underflow here and explicitly signal an underflow. The
|
|
| 239 | + * constant here is from core-math exp.c.
|
|
| 240 | + */
|
|
| 241 | + if (x <= -0x1.74910d52d3052p+9) {
|
|
| 242 | + return fdlibm_setexception(0.0, FDLIBM_UNDERFLOW);
|
|
| 243 | + }
|
|
| 244 | + |
|
| 224 | 245 | return cr_exp(x);
|
| 225 | 246 | #else
|
| 226 | 247 | return __ieee754_exp(x);
|
| ... | ... | @@ -420,13 +420,9 @@ |
| 420 | 420 | (ext:with-float-traps-masked (:overflow)
|
| 421 | 421 | (assert-equal ext:double-float-positive-infinity
|
| 422 | 422 | (kernel:%exp 710d0)))
|
| 423 | - (let ((modes (ext:get-floating-point-modes)))
|
|
| 424 | - (unwind-protect
|
|
| 425 | - (progn
|
|
| 426 | - (ext:set-floating-point-modes :traps '(:underflow))
|
|
| 427 | - (assert-error 'floating-point-underflow
|
|
| 428 | - (kernel:%exp -1000d0)))
|
|
| 429 | - (apply #'ext:set-floating-point-modes modes)))
|
|
| 423 | + (ext:with-float-traps-enabled (:underflow)
|
|
| 424 | + (assert-error 'floating-point-underflow
|
|
| 425 | + (kernel:%exp -1000d0)))
|
|
| 430 | 426 | (let ((x (scale-float 1d0 -29))
|
| 431 | 427 | (x0 0d0))
|
| 432 | 428 | ;; exp(x) = x, |x| < 2^-28, with inexact exception unlees x = 0
|