Raymond Toy pushed to branch issue-425-correctly-rounded-math-functions at cmucl / cmucl
Commits:
-
5ff177cb
by Raymond Toy at 2025-08-13T15:06:30-07:00
2 changed files:
Changes:
| ... | ... | @@ -41,7 +41,7 @@ |
| 41 | 41 | #+core-math
|
| 42 | 42 | (:temporary (:sc unsigned-stack) fpu-cw)
|
| 43 | 43 | #+core-math
|
| 44 | - (:temporary (:sc unsigned-reg) temp-cw)
|
|
| 44 | + (:temporary (:sc unsigned-reg :offset esi-offset) temp-cw)
|
|
| 45 | 45 | (:node-var node)
|
| 46 | 46 | (:vop-var vop)
|
| 47 | 47 | (:save-p t)
|
| ... | ... | @@ -51,11 +51,14 @@ |
| 51 | 51 | #+core-math
|
| 52 | 52 | (progn
|
| 53 | 53 | ;; Save the x87 FPU control word. Then modify it to set the
|
| 54 | - ;; precision bits to double (2).
|
|
| 54 | + ;; precision bits to 3 for 64-bit mantissas for 80-bit
|
|
| 55 | + ;; arithmetic. If we don't some of some special functions
|
|
| 56 | + ;; return incorrect values because the x87 precision was set to
|
|
| 57 | + ;; single.
|
|
| 55 | 58 | (inst fnstcw save-fpu-cw)
|
| 56 | 59 | (move temp-cw save-fpu-cw)
|
| 57 | 60 | (inst and temp-cw (dpb 0 (byte 2 8) #xffff)) ; Zap the precision control bits
|
| 58 | - (inst or temp-cw (dpb 2 (byte 2 8) 0)) ; Set precision control to double
|
|
| 61 | + (inst or temp-cw (dpb 3 (byte 3 8) 0)) ; Set precision control bits
|
|
| 59 | 62 | (move fpu-cw temp-cw)
|
| 60 | 63 | (inst fldcw fpu-cw) ; New CW
|
| 61 | 64 | )
|
| ... | ... | @@ -245,3 +245,18 @@ |
| 245 | 245 | (tanh #c(200w0 200w0))))
|
| 246 | 246 |
|
| 247 | 247 |
|
| 248 | +(define-test cos-tiny
|
|
| 249 | + (:tag issues)
|
|
| 250 | + ;; This test comes from the Maxima testsuite where core-math was not
|
|
| 251 | + ;; computing cos(8.881784197001252d-16) correctly. It should be
|
|
| 252 | + ;; exactly 1. We were getting one bit less.
|
|
| 253 | + (assert-eql 1d0
|
|
| 254 | + (cos (kernel:make-double-float 1020264448 0))))
|
|
| 255 | + |
|
| 256 | +(define-test log.special-value
|
|
| 257 | + (:tag issues)
|
|
| 258 | + ;; This test comes from the Maxima testsuite where core-math was not
|
|
| 259 | + ;; computing log(0.6899991035461426d0) => -0.37106498060016496d0.
|
|
| 260 | + ;; The computed result looked it had like a single-precision accuracy.
|
|
| 261 | + (assert-eql -0.37106498060016496d0
|
|
| 262 | + (kernel:%log (kernel:make-double-float (+ 1071644672 398457) 0)))) |