Raymond Toy pushed to branch rtoy-fix-59-derive-decode-float at cmucl / cmucl

Commits:

3 changed files:

Changes:

  • src/compiler/float-tran.lisp
    ... ... @@ -2031,29 +2031,33 @@
    2031 2031
       (labels
    
    2032 2032
           ((calc-exp (x)
    
    2033 2033
     	 (when x
    
    2034
    -	   (nth-value 1 (decode-float x))))
    
    2035
    -       (min-exp ()
    
    2036
    -	 ;; Use decode-float on the least positive float of the
    
    2037
    -	 ;; appropriate type to find the min exponent.  If we don't
    
    2038
    -	 ;; know the actual number format, use double, which has the
    
    2039
    -	 ;; widest range (including double-double-float).
    
    2040
    -	 (calc-exp (if (eq 'single-float (numeric-type-format arg))
    
    2041
    -		       least-positive-single-float
    
    2042
    -		       least-positive-double-float)))
    
    2043
    -       (max-exp ()
    
    2034
    +	   (bound-func #'(lambda (arg)
    
    2035
    +			   (nth-value 1 (decode-float arg)))
    
    2036
    +		       x)))
    
    2037
    +       (min-exp (interval)
    
    2038
    +	 ;; (decode-float 0d0) returns an exponent of -1022.  But
    
    2039
    +	 ;; (decode-float least-positive-double-float returns -1073.
    
    2040
    +	 ;; Hence, if the low value is less than this, we need to
    
    2041
    +	 ;; return the exponent of the least positive number.
    
    2042
    +	 (let ((least (if (eq 'single-float (numeric-type-format arg))
    
    2043
    +			  least-positive-single-float
    
    2044
    +			  least-positive-double-float)))
    
    2045
    +	   (if (or (interval-contains-p 0 interval)
    
    2046
    +		   (interval-contains-p least interval))
    
    2047
    +	     (calc-exp least)
    
    2048
    +	     (calc-exp (bound-value (interval-low interval))))))
    
    2049
    +       (max-exp (interval)
    
    2044 2050
     	 ;; Use decode-float on the most postive number of the
    
    2045 2051
     	 ;; appropriate type to find the max exponent.  If we don't
    
    2046 2052
     	 ;; know the actual number format, use double, which has the
    
    2047 2053
     	 ;; widest range (including double-double-float).
    
    2048
    -	 (calc-exp (if (eq 'single-float (numeric-type-format arg))
    
    2049
    -		       most-positive-single-float
    
    2050
    -		       most-positive-double-float))))
    
    2051
    -    (let* ((interval (interval-func #'calc-exp
    
    2052
    -				    (interval-abs (numeric-type->interval arg))))
    
    2053
    -	   (lo (or (interval-low interval)
    
    2054
    -		   (min-exp)))
    
    2055
    -	   (hi (or (interval-high interval)
    
    2056
    -		   (max-exp))))
    
    2054
    +	 (or (calc-exp (bound-value (interval-high interval)))
    
    2055
    +	     (calc-exp (if (eq 'single-float (numeric-type-format arg))
    
    2056
    +			   most-positive-single-float
    
    2057
    +			   most-positive-double-float)))))
    
    2058
    +    (let* ((interval (interval-abs (numeric-type->interval arg)))
    
    2059
    +	   (lo (min-exp interval))
    
    2060
    +	   (hi (max-exp interval)))
    
    2057 2061
           (specifier-type `(integer ,(or lo '*) ,(or hi '*))))))
    
    2058 2062
     
    
    2059 2063
     (defun decode-float-sign-derive-type-aux (arg)
    

  • tests/float-tran.lisp
    ... ... @@ -28,7 +28,7 @@
    28 28
       #+double-double
    
    29 29
       (assert-equalp (c::specifier-type '(integer -1073 1024))
    
    30 30
     		 (c::decode-float-exp-derive-type-aux
    
    31
    -		  (c::specifier-type 'double-double-float)))
    
    31
    +		  (c::specifier-type 'kernel:double-double-float)))
    
    32 32
       (assert-equalp (c::specifier-type '(integer 2 8))
    
    33 33
     		 (c::decode-float-exp-derive-type-aux
    
    34 34
     		  (c::specifier-type '(double-float 2d0 128d0)))))
    

  • tests/issues.lisp
    ... ... @@ -450,3 +450,57 @@
    450 450
     			    (declare (type (double-float -2d0 0d0) z))
    
    451 451
     			    (nth-value 2 (decode-float z))))))
    
    452 452
         (assert-equal -1d0 (funcall f -1d0))))
    
    453
    +
    
    454
    +(define-test issue.59.1-double
    
    455
    +  (:tag :issues)
    
    456
    +  (dolist (entry '(((-2d0 2d0) (-1073 2))
    
    457
    +		   ((-2d0 0d0) (-1073 2))
    
    458
    +		   ((0d0 2d0) (-1073 2))
    
    459
    +		   ((1d0 4d0) (1 3))
    
    460
    +		   ((-4d0 -1d0) (1 3))
    
    461
    +		   (((0d0) (10d0)) (-1073 4))
    
    462
    +		   ((-2f0 2f0) (-148 2))
    
    463
    +		   ((-2f0 0f0) (-148 2))
    
    464
    +		   ((0f0 2f0) (-148 2))
    
    465
    +		   ((1f0 4f0) (1 3))
    
    466
    +		   ((-4f0 -1f0) (1 3))
    
    467
    +		   ((0f0) (10f0)) (-148 4)))
    
    468
    +    (destructuring-bind ((arg-lo arg-hi) (result-lo result-hi))
    
    469
    +	entry
    
    470
    +      (assert-equalp (c::specifier-type `(integer ,result-lo ,result-hi))
    
    471
    +		     (c::decode-float-exp-derive-type-aux
    
    472
    +		      (c::specifier-type `(double-float ,arg-lo ,arg-hi)))))))
    
    473
    +
    
    474
    +(define-test issue.59.1-double
    
    475
    +  (:tag :issues)
    
    476
    +  (dolist (entry '(((-2d0 2d0) (-1073 2))
    
    477
    +		   ((-2d0 0d0) (-1073 2))
    
    478
    +		   ((0d0 2d0) (-1073 2))
    
    479
    +		   ((1d0 4d0) (1 3))
    
    480
    +		   ((-4d0 -1d0) (1 3))
    
    481
    +		   (((0d0) (10d0)) (-1073 4))
    
    482
    +		   (((0.5d0) (4d0)) (0 3))))
    
    483
    +    (destructuring-bind ((arg-lo arg-hi) (result-lo result-hi))
    
    484
    +	entry
    
    485
    +      (assert-equalp (c::specifier-type `(integer ,result-lo ,result-hi))
    
    486
    +		     (c::decode-float-exp-derive-type-aux
    
    487
    +		      (c::specifier-type `(double-float ,arg-lo ,arg-hi)))
    
    488
    +		     arg-lo
    
    489
    +		     arg-hi))))
    
    490
    +
    
    491
    +(define-test issue.59.1-float
    
    492
    +  (:tag :issues)
    
    493
    +  (dolist (entry '(((-2f0 2f0) (-148 2))
    
    494
    +		   ((-2f0 0f0) (-148 2))
    
    495
    +		   ((0f0 2f0) (-148 2))
    
    496
    +		   ((1f0 4f0) (1 3))
    
    497
    +		   ((-4f0 -1f0) (1 3))
    
    498
    +		   (((0f0) (10f0)) (-148 4))
    
    499
    +		   (((0.5f0) (4f0)) (0 3))))
    
    500
    +    (destructuring-bind ((arg-lo arg-hi) (result-lo result-hi))
    
    501
    +	entry
    
    502
    +      (assert-equalp (c::specifier-type `(integer ,result-lo ,result-hi))
    
    503
    +		     (c::decode-float-exp-derive-type-aux
    
    504
    +		      (c::specifier-type `(single-float ,arg-lo ,arg-hi)))
    
    505
    +		     arg-lo
    
    506
    +		     arg-hi))))
    \ No newline at end of file