From 3acdd1b7d05d9a90c877167e882bf77b22606366 Mon Sep 17 00:00:00 2001 From: Raymond Toy <toy.raymond@gmail.com> Date: Sat, 3 Feb 2018 08:57:28 -0800 Subject: [PATCH] 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. --- src/compiler/float-tran.lisp | 47 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/compiler/float-tran.lisp b/src/compiler/float-tran.lisp index e89952790..1ee030bd0 100644 --- a/src/compiler/float-tran.lisp +++ b/src/compiler/float-tran.lisp @@ -2028,30 +2028,31 @@ (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) - (when x - (nth-value 1 (decode-float x)))) - (min-exp () - ;; Use decode-float on the least positive float of the - ;; 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)) - least-positive-single-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)) + (labels + ((calc-exp (x) + (when x + (nth-value 1 (decode-float x)))) + (min-exp () + ;; Use decode-float on the least positive float of the + ;; 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). + (calc-exp (if (eq 'single-float (numeric-type-format arg)) + least-positive-single-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). + (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 '*)))))) -- GitLab