Raymond Toy pushed to branch issue-275b-signal-float-underflow at cmucl / cmucl
Commits: ba400bf5 by Raymond Toy at 2024-03-29T07:11:07-07:00 Signal reader-error on underflow instead of FP underflow.
The error message makes it clear we have a FP underflow like so: ``` * 1d-308
Reader error on #<Two-Way Stream, Input = #<Synonym Stream to SYSTEM:*STDIN*>, Output = #<Synonym Stream to SYSTEM:*STDOUT*>>: Underflow when reading "1d-308" [Condition of type READER-ERROR]
Restarts: 0: [CONTINUE] Return 0.0d0 1: [ABORT ] Return to Top-Level.
```
- - - - - f3d64ced by Raymond Toy at 2024-03-29T07:16:02-07:00 Change message to mention floating point
Instead of just saying "Underflow when reading...", say "Floating point underflow when reading..." to make it a bit clearer what happened.
- - - - - 4ba5145d by Raymond Toy at 2024-03-29T07:20:32-07:00 Undo some space changes and correct a comment.
Undo some tab vs space changes at the end of make-float-aux.
The comment about double-float exponent range was in the wrong place so put it in the right place.
- - - - - e1a35617 by Raymond Toy at 2024-03-29T07:55:55-07:00 Test FP underflow signals reader-error
We now signal a `reader-error` on a FP underflow. Thus, test that we get a reader error. Also test that the message says we got an underflow. This is to verify that we tell the user that it's an underflow and not some other reader error.
- - - - - 031b5ce0 by Raymond Toy at 2024-03-29T07:58:47-07:00 Update pot file for updated message string.
- - - - - 047a0f08 by Raymond Toy at 2024-03-29T08:00:08-07:00 Add comment on where the expected string comes from.
- - - - -
3 changed files:
- src/code/reader.lisp - src/i18n/locale/cmucl.pot - tests/float.lisp
Changes:
===================================== src/code/reader.lisp ===================================== @@ -1855,12 +1855,12 @@ the end of the stream." vm:single-float-bias)))) ((double-float long-float #+double-double kernel:double-double-float) + ;; Double-float exponent range is -1074 to -1023 (values (* 2 (- vm:double-float-normal-exponent-min vm:double-float-bias vm:double-float-digits)) (* 2 (- vm:double-float-normal-exponent-max vm:double-float-bias))))) - ;; Double-float exponent range is -1074 to -1023 (unless (< log2-low log2-num log2-high) ;; The number is definitely too large or too small to fit. ;; Signal an error. @@ -1879,18 +1879,19 @@ the end of the stream." (error _"Underflow")) result) (floating-point-underflow () - ;; Resignal the underflow, but allow the user to continue with + ;; Resignal a reader error, but allow the user to continue with ;; 0. (let ((zero (coerce 0 float-format))) (restart-case - (error 'floating-point-underflow) + (%reader-error stream _"Floating point underflow when reading ~S" + (read-buffer-to-string)) (continue () :report (lambda (stream) (format stream "Return ~A" zero)) zero)))) (error () - (%reader-error stream _"Number not representable as a ~S: ~S" - float-format (read-buffer-to-string))))) + (%reader-error stream _"Number not representable as a ~S: ~S" + float-format (read-buffer-to-string)))))
(defun make-ratio (stream)
===================================== src/i18n/locale/cmucl.pot ===================================== @@ -8731,6 +8731,14 @@ msgstr "" msgid "Number not representable as a ~S: ~S" msgstr ""
+#: src/code/reader.lisp +msgid "Underflow" +msgstr "" + +#: src/code/reader.lisp +msgid "Floating point underflow when reading ~S" +msgstr "" + #: src/code/reader.lisp msgid "Invalid ratio: ~S/~S" msgstr ""
===================================== tests/float.lisp ===================================== @@ -217,12 +217,31 @@ (:tag :issues) (lisp::with-float-traps-enabled (:underflow) ;; A denormal - (assert-error 'floating-point-underflow + (assert-error 'reader-error (read-from-string "1e-40")) - (assert-error 'floating-point-underflow + (assert-error 'reader-error (read-from-string (format nil "~A" least-positive-single-float))) ;; The same for double-floats - (assert-error 'floating-point-underflow + (assert-error 'reader-error (read-from-string "1d-308")) - (assert-error 'floating-point-underflow + (assert-error 'reader-error (read-from-string (format nil "~A" least-positive-double-float))))) + +(define-test reader.float-underflow + (:tag :issues) + (lisp::with-float-traps-enabled (:underflow) + ;; The expected string comes from make-float-aux. + (let ((expected "Floating point underflow when reading ~S")) + (flet ((test-reader-underflow (string) + ;; Test that the we got a reader-error when a number + ;; would underflow and that the message says we got an + ;; underflow. + (let ((condition (nth-value 1 (ignore-errors (read-from-string string))))) + (assert-equal 'reader-error (type-of condition)) + (assert-equal expected (lisp::reader-error-format-control condition))))) + ;; Underflow single-floats + (test-reader-underflow "1e-40") + (test-reader-underflow (format nil "~A" least-positive-single-float)) + ;; Underflow double-floats + (test-reader-underflow "1d-308") + (test-reader-underflow (format nil "~A" least-positive-double-float))))))
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/bb8eb44c424cc0ab2dba0e4...