Skip to content
Snippets Groups Projects
Commit 4e58e53c authored by Raymond Toy's avatar Raymond Toy
Browse files

Be more careful in computing the decode-float bounds

If 0 is the lower bound then the smallest exponent is not for 0, but
for the least positive float because of denormals.

Also handle exclusive bounds.
parent 2292400e
No related branches found
No related tags found
No related merge requests found
...@@ -2031,29 +2031,33 @@ ...@@ -2031,29 +2031,33 @@
(labels (labels
((calc-exp (x) ((calc-exp (x)
(when x (when x
(nth-value 1 (decode-float x)))) (bound-func #'(lambda (arg)
(min-exp () (nth-value 1 (decode-float arg)))
;; Use decode-float on the least positive float of the x)))
;; appropriate type to find the min exponent. If we don't (min-exp (interval)
;; know the actual number format, use double, which has the ;; (decode-float 0d0) returns an exponent of -1022. But
;; widest range (including double-double-float). ;; (decode-float least-positive-double-float returns -1073.
(calc-exp (if (eq 'single-float (numeric-type-format arg)) ;; Hence, if the low value is less than this, we need to
least-positive-single-float ;; return the exponent of the least positive number.
least-positive-double-float))) (let ((least (if (eq 'single-float (numeric-type-format arg))
(max-exp () least-positive-single-float
least-positive-double-float)))
(if (or (interval-contains-p 0 interval)
(interval-contains-p least interval))
(calc-exp least)
(calc-exp (bound-value (interval-low interval))))))
(max-exp (interval)
;; Use decode-float on the most postive number of the ;; Use decode-float on the most postive number of the
;; appropriate type to find the max exponent. If we don't ;; appropriate type to find the max exponent. If we don't
;; know the actual number format, use double, which has the ;; know the actual number format, use double, which has the
;; widest range (including double-double-float). ;; widest range (including double-double-float).
(calc-exp (if (eq 'single-float (numeric-type-format arg)) (or (calc-exp (bound-value (interval-high interval)))
most-positive-single-float (calc-exp (if (eq 'single-float (numeric-type-format arg))
most-positive-double-float)))) most-positive-single-float
(let* ((interval (interval-func #'calc-exp most-positive-double-float)))))
(interval-abs (numeric-type->interval arg)))) (let* ((interval (interval-abs (numeric-type->interval arg)))
(lo (or (interval-low interval) (lo (min-exp interval))
(min-exp))) (hi (max-exp interval)))
(hi (or (interval-high interval)
(max-exp))))
(specifier-type `(integer ,(or lo '*) ,(or hi '*)))))) (specifier-type `(integer ,(or lo '*) ,(or hi '*))))))
(defun decode-float-sign-derive-type-aux (arg) (defun decode-float-sign-derive-type-aux (arg)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment