Commit 3acdd1b7 authored by Raymond Toy's avatar Raymond Toy
Browse files

Fix #59: type derivation for decode-float exponent

Type derivation for exponent part of decode-float was incorrect.  We
need to take the absolute value of the argument before deriving the
type since the exponent is, of course, independent of the sign of the
number.  In the test case, the negative interval caused the lower and
upper bounds to be reversed, resulting in an invalid interval.
parent e7f97a5d
Loading
Loading
Loading
Loading
+24 −23
Original line number Diff line number Diff line
@@ -2028,7 +2028,8 @@
(defun decode-float-exp-derive-type-aux (arg)
  ;; Derive the exponent part of the float.  It's always an integer
  ;; type.
  (flet ((calc-exp (x)
  (labels
      ((calc-exp (x)
	 (when x
	   (nth-value 1 (decode-float x))))
       (min-exp ()
@@ -2036,22 +2037,22 @@
	 ;; appropriate type to find the min exponent.  If we don't
	 ;; know the actual number format, use double, which has the
	 ;; widest range (including double-double-float).
	   (nth-value 1 (decode-float (if (eq 'single-float (numeric-type-format arg))
	 (calc-exp (if (eq 'single-float (numeric-type-format arg))
		       least-positive-single-float
					  least-positive-double-float))))
		       least-positive-double-float)))
       (max-exp ()
	 ;; Use decode-float on the most postive number of the
	 ;; appropriate type to find the max exponent.  If we don't
	 ;; know the actual number format, use double, which has the
	 ;; widest range (including double-double-float).
	   (if (eq (numeric-type-format arg) 'single-float)
	       (nth-value 1 (decode-float most-positive-single-float))
	       (nth-value 1 (decode-float most-positive-double-float)))))
    (let* ((lo (or (bound-func #'calc-exp
			       (numeric-type-low arg))
	 (calc-exp (if (eq 'single-float (numeric-type-format arg))
		       most-positive-single-float
		       most-positive-double-float))))
    (let* ((interval (interval-func #'calc-exp
				    (interval-abs (numeric-type->interval arg))))
	   (lo (or (interval-low interval)
		   (min-exp)))
	   (hi (or (bound-func #'calc-exp
			       (numeric-type-high arg))
	   (hi (or (interval-high interval)
		   (max-exp))))
      (specifier-type `(integer ,(or lo '*) ,(or hi '*))))))