Raymond Toy pushed to branch issue-425-correctly-rounded-math-functions-single-float at cmucl / cmucl Commits: 31c76e8b by Raymond Toy at 2026-02-17T14:21:27-08:00 Signal errors for singles as we do for double. Add tests for coshf For the the single-float core-math routines, add the corresponding error checks that we do for double-floats. Add tests for these exceptional cases for coshf, based on the same tests for cosh. Curiously, cr_cosh(inf) silently returns inf but cr_coshf(inf) signals a division by 0. So make this consistent by checking for infinity values and signaling an error if enabled. - - - - - 3e89a81c by Raymond Toy at 2026-02-17T14:29:31-08:00 cosh(+/-inf) = +inf if overflow is disabled. We accidentally returned -inf for cosh(-inf). Of course, it should be +inf. Update irrat.c for this and add tests for this too. ( - - - - - 2 changed files: - src/lisp/irrat.c - tests/fdlibm.lisp Changes: ===================================== src/lisp/irrat.c ===================================== @@ -163,6 +163,8 @@ double lisp_cosh(double x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_OVERFLOW(fabs(x)) + return cr_cosh(x); #else return __ieee754_cosh(x); @@ -319,6 +321,8 @@ float lisp_sinf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_INVALID(isinf(x), x) + return cr_sinf(x); #else return (float) fdlibm_sin((double) x); @@ -329,6 +333,8 @@ float lisp_cosf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_INVALID(isinf(x), x) + return cr_cosf(x); #else return (float) fdlibm_cos((double) x); @@ -339,6 +345,8 @@ float lisp_tanf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_INVALID(isinf(x), x) + return cr_tanf(x); #else return (float) fdlibm_tan((double) x); @@ -389,6 +397,8 @@ float lisp_sinhf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_OVERFLOW(x) + return cr_sinhf(x); #else return (float) __ieee754_sinh((double) x); @@ -399,6 +409,8 @@ float lisp_coshf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_OVERFLOW(fabs(x)) + return cr_coshf(x); #else return (float) __ieee754_cosh((double) x); @@ -419,6 +431,8 @@ float lisp_asinhf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_OVERFLOW(x) + return cr_asinhf(x); #else return (float) fdlibm_asinh((double) x); @@ -429,6 +443,10 @@ float lisp_acoshf(float x) { #ifdef FEATURE_CORE_MATH + MAYBE_SIGNAL_INVALID(x < 1, x) + + MAYBE_SIGNAL_OVERFLOW(x) + return cr_acoshf(x); #else return (float) __ieee754_acosh((double) x); ===================================== tests/fdlibm.lisp ===================================== @@ -8,14 +8,23 @@ (defparameter *qnan* (ext:with-float-traps-masked (:invalid) (* 0 ext:double-float-positive-infinity)) - "Some randon quiet MaN value") + "Some randon quiet double-float MaN value") + +(defparameter *qnan-single-float* + (ext:with-float-traps-masked (:invalid) + (* 0 ext:single-float-positive-infinity)) + "Some randon quiet single-float MaN value") (defparameter *snan* (kernel:make-double-float #x7ff00000 1) - "A randon signaling MaN value") + "A randon signaling double-float MaN value") + +(defparameter *snan-single-float* + (kernel:make-single-float #x7f800001) + "A randon signaling single-float MaN value") (define-test %cosh.exceptions - (:tag :fdlibm) + (:tag :fdlibm) (assert-error 'floating-point-overflow (kernel:%cosh 1000d0)) (assert-error 'floating-point-overflow @@ -23,6 +32,10 @@ (assert-error 'floating-point-invalid-operation (kernel:%cosh *snan*)) (assert-true (ext:float-nan-p (kernel:%cosh *qnan*))) + (assert-error 'floating-point-overflow + (kernel:%cosh ext:double-float-positive-infinity)) + (assert-error 'floating-point-overflow + (kernel:%cosh ext:double-float-negative-infinity)) ;; Same, but with overflow's masked (ext:with-float-traps-masked (:overflow) @@ -38,6 +51,34 @@ (ext:with-float-traps-masked (:invalid) (assert-true (ext:float-nan-p (kernel:%cosh *snan*))))) +(define-test %coshf.exceptions + (:tag :fdlibm) + (assert-error 'floating-point-overflow + (kernel:%coshf 100f0)) + (assert-error 'floating-point-overflow + (kernel:%coshf -100f0)) + (assert-error 'floating-point-invalid-operation + (kernel:%coshf *snan-single-float*)) + (assert-true (ext:float-nan-p (kernel:%coshf *qnan-single-float*))) + (assert-error 'floating-point-overflow + (kernel:%coshf ext:single-float-positive-infinity)) + (assert-error 'floating-point-overflow + (kernel:%coshf ext:single-float-negative-infinity)) + + ;; Same, but with overflow's masked + (ext:with-float-traps-masked (:overflow) + (assert-equal ext:single-float-positive-infinity + (kernel:%coshf 100f0)) + (assert-equal ext:single-float-positive-infinity + (kernel:%coshf -100f0)) + (assert-equal ext:single-float-positive-infinity + (kernel:%coshf ext:single-float-positive-infinity)) + (assert-equal ext:single-float-positive-infinity + (kernel:%coshf ext:single-float-negative-infinity))) + ;; Test NaN + (ext:with-float-traps-masked (:invalid) + (assert-true (ext:float-nan-p (kernel:%coshf *snan-single-float*))))) + (define-test %sinh.exceptions (:tag :fdlibm) (assert-error 'floating-point-overflow @@ -47,6 +88,7 @@ (assert-error 'floating-point-invalid-operation (kernel:%sinh *snan*)) (assert-true (ext:float-nan-p (kernel:%sinh *qnan*))) + ;; Same, but with overflow's masked (ext:with-float-traps-masked (:overflow) (assert-equal ext:double-float-positive-infinity View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/70bd3787f0128805658e836... -- View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/70bd3787f0128805658e836... You're receiving this email because of your account on gitlab.common-lisp.net.
participants (1)
-
Raymond Toy (@rtoy)