Raymond Toy pushed to branch issue-425-correctly-rounded-math-functions-single-float at cmucl / cmucl Commits: a5f3dc8a by Raymond Toy at 2026-02-18T19:22:08-08:00 Add tests for %powf based on the tests for %pow There are currently many failed tests: (FDLIBM-TESTS::%POWF.CASE.13 FDLIBM-TESTS::%POWF.CASE.12 FDLIBM-TESTS::%POWF.CASE.9 FDLIBM-TESTS::%POWF.CASE.8 FDLIBM-TESTS::%POWF.CASE.5 FDLIBM-TESTS::%POWF.CASE.4 FDLIBM-TESTS::%POWF.CASE.3) - - - - - 59387511 by Raymond Toy at 2026-02-18T19:41:20-08:00 Use single-float versions of qNaN and sNaN In a few places we forgot to use the single-float versions of `*qnan*` and `*snan*`. This fixes many tests, but we still fail (FDLIBM-TESTS::%POWF.CASE.13 FDLIBM-TESTS::%POWF.CASE.12 FDLIBM-TESTS::%POWF.CASE.8 FDLIBM-TESTS::%POWF.CASE.5) These signal division-by-zero instead of silently returning an infinity. - - - - - 1 changed file: - tests/fdlibm.lisp Changes: ===================================== tests/fdlibm.lisp ===================================== @@ -1062,6 +1062,14 @@ (assert-equal 1d0 (kernel:%pow ext:double-float-negative-infinity 0d0))) +(define-test %powf.case.1 + (:tag :fdlibm) + ;; anything ^ 0 is 1 + (assert-equal 1f0 + (kernel:%powf ext:single-float-positive-infinity 0f0)) + (assert-equal 1f0 + (kernel:%powf ext:single-float-negative-infinity 0f0))) + (define-test %pow.case.2 (:tag :fdlibm) ;; anything ^ 1 is itself @@ -1070,6 +1078,14 @@ (assert-equal ext:double-float-negative-infinity (kernel:%pow ext:double-float-negative-infinity 1d0))) +(define-test %powf.case.2 + (:tag :fdlibm) + ;; anything ^ 1 is itself + (assert-equal ext:single-float-positive-infinity + (kernel:%powf ext:single-float-positive-infinity 1f0)) + (assert-equal ext:single-float-negative-infinity + (kernel:%powf ext:single-float-negative-infinity 1f0))) + (define-test %pow.case.3 (:tag :fdlibm) ;; anything ^ NaN is NaN @@ -1078,6 +1094,14 @@ (assert-true (ext:float-nan-p (kernel:%pow ext:double-float-positive-infinity *qnan*)))) +(define-test %powf.case.3 + (:tag :fdlibm) + ;; anything ^ NaN is NaN + (assert-true (ext:float-nan-p + (kernel:%powf (float pi 1f0) *qnan-single-float*))) + (assert-true (ext:float-nan-p + (kernel:%powf ext:single-float-positive-infinity *qnan-single-float*)))) + (define-test %pow.case.4 (:tag :fdlibm) ;; NaN ^ non-zero is NaN @@ -1086,6 +1110,14 @@ (assert-true (ext:float-nan-p (kernel:%pow *qnan* ext:double-float-positive-infinity)))) +(define-test %powf.case.4 + (:tag :fdlibm) + ;; NaN ^ non-zero is NaN + (assert-true (ext:float-nan-p + (kernel:%powf *qnan-single-float* (float pi 1f0)))) + (assert-true (ext:float-nan-p + (kernel:%powf *qnan-single-float* ext:single-float-positive-infinity)))) + (define-test %pow.case.5 (:tag :fdlibm) ;; (|x| > 1) ^ +inf is +inf @@ -1094,6 +1126,14 @@ (assert-equal ext:double-float-positive-infinity (kernel:%pow (- pi) ext:double-float-positive-infinity))) +(define-test %powf.case.5 + (:tag :fdlibm) + ;; (|x| > 1) ^ +inf is +inf + (assert-equal ext:single-float-positive-infinity + (kernel:%powf (float pi 1f0) ext:single-float-positive-infinity)) + (assert-equal ext:single-float-positive-infinity + (kernel:%powf (float (- pi) 1f0) ext:single-float-positive-infinity))) + (define-test %pow.case.6 (:tag :fdlibm) ;; (|x| > 1) ^ -inf is +0 @@ -1102,6 +1142,14 @@ (assert-equal +0d0 (kernel:%pow (- pi) ext:double-float-negative-infinity))) +(define-test %powf.case.6 + (:tag :fdlibm) + ;; (|x| > 1) ^ -inf is +0 + (assert-equal +0f0 + (kernel:%powf (float pi 1f0) ext:single-float-negative-infinity)) + (assert-equal +0f0 + (kernel:%powf (float (- pi) 1f0) ext:single-float-negative-infinity))) + (define-test %pow.case.7 (:tag :fdlibm) ;; (|x| < 1) ^ +inf is +0 @@ -1110,6 +1158,14 @@ (assert-equal +0d0 (kernel:%pow -0.5d0 ext:double-float-positive-infinity))) +(define-test %powf.case.7 + (:tag :fdlibm) + ;; (|x| < 1) ^ +inf is +0 + (assert-equal +0f0 + (kernel:%powf 0.5f0 ext:single-float-positive-infinity)) + (assert-equal +0f0 + (kernel:%powf -0.5f0 ext:single-float-positive-infinity))) + (define-test %pow.case.8 (:tag :fdlibm) ;; (|x| < 1) ^ -inf is +inf @@ -1118,6 +1174,14 @@ (assert-equal ext:double-float-positive-infinity (kernel:%pow -0.5d0 ext:double-float-negative-infinity))) +(define-test %powf.case.8 + (:tag :fdlibm) + ;; (|x| < 1) ^ -inf is +inf + (assert-equal ext:single-float-positive-infinity + (kernel:%powf 0.5f0 ext:single-float-negative-infinity)) + (assert-equal ext:single-float-positive-infinity + (kernel:%powf -0.5f0 ext:single-float-negative-infinity))) + (define-test %pow.case.9 (:tag :fdlibm) ;; std::pow says 1^exp is 1 for any exp, including NaN. (-1)^(+/-inf) @@ -1159,6 +1223,47 @@ (assert-true (ext:float-nan-p (kernel:%pow -1d0 ext:double-float-negative-infinity)))))) +(define-test %powf.case.9 + (:tag :fdlibm) + ;; std::pow says 1^exp is 1 for any exp, including NaN. (-1)^(+/-inf) + ;; is 1. No errors signaled. + #+core-math + (progn + (assert-equal 1f0 + (kernel:%powf 1f0 ext:single-float-positive-infinity)) + (assert-equal 1f0 + (kernel:%powf 1f0 ext:single-float-negative-infinity)) + (assert-equal 1f0 + (kernel:%powf 1f0 *qnan-single-float*)) + (assert-equal 1f0 + (kernel:%powf -1f0 ext:single-float-positive-infinity)) + (assert-equal 1f0 + (kernel:%powf -1f0 ext:single-float-negative-infinity))) + #-core-math + ;; +-1 ^ +-inf is NaN. + ;; + ;; But the implementation signals invalid operation, so we need to + ;; check for that. + ;; + (progn + (assert-error 'floating-point-invalid-operation + (kernel:%powf 1f0 ext:single-float-positive-infinity)) + (assert-error 'floating-point-invalid-operation + (kernel:%powf 1f0 ext:single-float-negative-infinity)) + (assert-error 'floating-point-invalid-operation + (kernel:%powf -1f0 ext:single-float-positive-infinity)) + (assert-error 'floating-point-invalid-operation + (kernel:%powf -1f0 ext:single-float-negative-infinity)) + (ext:with-float-traps-masked (:invalid) + (assert-true (ext:float-nan-p + (kernel:%powf 1f0 ext:single-float-positive-infinity))) + (assert-true (ext:float-nan-p + (kernel:%powf 1f0 ext:single-float-negative-infinity))) + (assert-true (ext:float-nan-p + (kernel:%powf -1f0 ext:single-float-positive-infinity))) + (assert-true (ext:float-nan-p + (kernel:%powf -1f0 ext:single-float-negative-infinity)))))) + (define-test %pow.case.10 (:tag :fdlibm) ;; +0 ^ (+anything except 0, Nan) is +0 @@ -1167,6 +1272,14 @@ (assert-equal +0d0 (kernel:%pow +0d0 ext:double-float-positive-infinity))) +(define-test %powf.case.10 + (:tag :fdlibm) + ;; +0 ^ (+anything except 0, Nan) is +0 + (assert-equal +0f0 + (kernel:%powf +0f0 10f0)) + (assert-equal +0f0 + (kernel:%powf +0f0 ext:single-float-positive-infinity))) + (define-test %pow.case.11 (:tag :fdlibm) ;; +0 ^ (+anything except 0, Nan, odd integer) is +0 @@ -1175,6 +1288,14 @@ (assert-equal +0d0 (kernel:%pow -0d0 ext:double-float-positive-infinity))) +(define-test %powf.case.11 + (:tag :fdlibm) + ;; +0 ^ (+anything except 0, Nan, odd integer) is +0 + (assert-equal +0f0 + (kernel:%powf -0f0 10f0)) + (assert-equal +0f0 + (kernel:%powf -0f0 ext:single-float-positive-infinity))) + (define-test %pow.case.12 (:tag :fdlibm) ;; +0 ^ (-anything except 0, Nan) is +inf @@ -1189,6 +1310,22 @@ (assert-equal ext:double-float-positive-infinity (kernel:%pow +0d0 ext:double-float-negative-infinity))) +(define-test %powf.case.12 + (:tag :fdlibm) + ;; +0 ^ (-anything except 0, Nan) is +inf + ;; + ;; But fdlibm signals error for (+0)^(-10) instead of returning inf. Check this. + #+nil + (assert-error 'division-by-zero + (kernel:%powf +0f0 -10f0)) + #+nil + (ext:with-float-traps-masked (:divide-by-zero) + (assert-equal ext:single-float-positive-infinity + (kernel:%powf +0f0 -10f0))) + ;; No signals here. + (assert-equal ext:single-float-positive-infinity + (kernel:%powf +0f0 ext:single-float-negative-infinity))) + (define-test %pow.case.13 (:tag :fdlibm) ;; -0 ^ (-anything except 0, Nan, odd integer) is +inf @@ -1203,24 +1340,56 @@ (assert-equal ext:double-float-positive-infinity (kernel:%pow +0d0 ext:double-float-negative-infinity))) +(define-test %powf.case.13 + (:tag :fdlibm) + ;; -0 ^ (-anything except 0, Nan, odd integer) is +inf + ;; + ;; But (-0)^(-10) signals division by zero + (assert-error 'division-by-zero + (kernel:%powf -0f0 -10f0)) + (ext:with-float-traps-masked (:divide-by-zero) + (assert-equal ext:single-float-positive-infinity + (kernel:%powf -0f0 -10f0))) + ;; But no error here. + (assert-equal ext:single-float-positive-infinity + (kernel:%powf +0f0 ext:single-float-negative-infinity))) + (define-test %pow.case.14 (:tag :fdlibm) ;; -0 ^ (odd integer) = -( +0 ^ (odd integer)) (assert-equal (- (kernel:%pow +0d0 5d0)) (kernel:%pow -0d0 5d0))) +(define-test %powf.case.14 + (:tag :fdlibm) + ;; -0 ^ (odd integer) = -( +0 ^ (odd integer)) + (assert-equal (- (kernel:%powf +0f0 5f0)) + (kernel:%powf -0f0 5f0))) + (define-test %pow.case.15 (:tag :fdlibm) ;; +inf ^ (+anything except 0, NaN) is +inf (assert-equal ext:double-float-positive-infinity (kernel:%pow ext:double-float-positive-infinity pi))) +(define-test %powf.case.15 + (:tag :fdlibm) + ;; +inf ^ (+anything except 0, NaN) is +inf + (assert-equal ext:single-float-positive-infinity + (kernel:%powf ext:single-float-positive-infinity (float pi 1f0)))) + (define-test %pow.case.16 (:tag :fdlibm) ;; +inf ^ (-anything except 0, NaN) is +0 (assert-equal +0d0 (kernel:%pow ext:double-float-positive-infinity (- pi)))) +(define-test %powf.case.16 + (:tag :fdlibm) + ;; +inf ^ (-anything except 0, NaN) is +0 + (assert-equal +0f0 + (kernel:%powf ext:single-float-positive-infinity (float (- pi) 1f0)))) + (define-test %pow.case.17 (:tag :fdlibm) ;; -inf ^ (anything) = -0 ^ (-anything) @@ -1232,6 +1401,17 @@ (assert-equal (kernel:%pow -0d0 pi) (kernel:%pow ext:double-float-negative-infinity (- pi)))) +(define-test %powf.case.17 + (:tag :fdlibm) + ;; -inf ^ (anything) = -0 ^ (-anything) + (assert-equal (ext:with-float-traps-masked (:divide-by-zero) + ;; This produces a divide-by-zero error so mask it + ;; to get a value. + (kernel:%powf -0f0 (float (- pi) 1f0))) + (kernel:%powf ext:single-float-negative-infinity (float pi 1f0))) + (assert-equal (kernel:%powf -0f0 (float pi 1f0)) + (kernel:%powf ext:single-float-negative-infinity (float (- pi) 1f0)))) + (define-test %pow.case.18 (:tag :fdlibm) ;; (-anything) ^ integer is (-1)^integer * (+anything ^ integer) @@ -1242,6 +1422,16 @@ (kernel:%pow base (coerce power 'double-float)) base power)))) +(define-test %powf.case.18 + (:tag :fdlibm) + ;; (-anything) ^ integer is (-1)^integer * (+anything ^ integer) + (dolist (base '(-2f0 -10f0)) + (dolist (power '(5 -5)) + (assert-equal (* (expt -1 power) + (kernel:%powf (- base) (coerce power 'single-float))) + (kernel:%powf base (coerce power 'single-float)) + base power)))) + (define-test %pow.case.19 (:tag :fdlibm) ;; (-anything except 0 and inf) ^ non-integer is NaN @@ -1252,3 +1442,14 @@ (ext:with-float-traps-masked (:invalid) (assert-true (ext:float-nan-p (kernel:%pow -2d0 1.5d0))))) + +(define-test %powf.case.19 + (:tag :fdlibm) + ;; (-anything except 0 and inf) ^ non-integer is NaN + ;; + ;; But this signals invalid, so check for that too. + (assert-error 'floating-point-invalid-operation + (kernel:%powf -2f0 1.5f0)) + (ext:with-float-traps-masked (:invalid) + (assert-true (ext:float-nan-p + (kernel:%powf -2f0 1.5f0))))) View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/84314210c115db75920939d... -- View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/84314210c115db75920939d... You're receiving this email because of your account on gitlab.common-lisp.net.