Raymond Toy pushed to branch master at cmucl / cmucl

Commits:

3 changed files:

Changes:

  • src/compiler/float-tran.lisp
    ... ... @@ -2028,31 +2028,36 @@
    2028 2028
     (defun decode-float-exp-derive-type-aux (arg)
    
    2029 2029
       ;; Derive the exponent part of the float.  It's always an integer
    
    2030 2030
       ;; type.
    
    2031
    -  (flet ((calc-exp (x)
    
    2032
    -	   (when x
    
    2033
    -	     (nth-value 1 (decode-float x))))
    
    2034
    -	 (min-exp ()
    
    2035
    -	   ;; Use decode-float on the least positive float of the
    
    2036
    -	   ;; appropriate type to find the min exponent.  If we don't
    
    2037
    -	   ;; know the actual number format, use double, which has the
    
    2038
    -	   ;; widest range (including double-double-float).
    
    2039
    -	   (nth-value 1 (decode-float (if (eq 'single-float (numeric-type-format arg))
    
    2040
    -					  least-positive-single-float
    
    2041
    -					  least-positive-double-float))))
    
    2042
    -	 (max-exp ()
    
    2043
    -	   ;; Use decode-float on the most postive number of the
    
    2044
    -	   ;; appropriate type to find the max exponent.  If we don't
    
    2045
    -	   ;; know the actual number format, use double, which has the
    
    2046
    -	   ;; widest range (including double-double-float).
    
    2047
    -	   (if (eq (numeric-type-format arg) 'single-float)
    
    2048
    -	       (nth-value 1 (decode-float most-positive-single-float))
    
    2049
    -	       (nth-value 1 (decode-float most-positive-double-float)))))
    
    2050
    -    (let* ((lo (or (bound-func #'calc-exp
    
    2051
    -			       (numeric-type-low arg))
    
    2052
    -		   (min-exp)))
    
    2053
    -	   (hi (or (bound-func #'calc-exp
    
    2054
    -			       (numeric-type-high arg))
    
    2055
    -		   (max-exp))))
    
    2031
    +  (labels
    
    2032
    +      ((calc-exp (x)
    
    2033
    +	 (when x
    
    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)
    
    2050
    +	 ;; Use decode-float on the most postive number of the
    
    2051
    +	 ;; appropriate type to find the max exponent.  If we don't
    
    2052
    +	 ;; know the actual number format, use double, which has the
    
    2053
    +	 ;; widest range (including double-double-float).
    
    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)))
    
    2056 2061
           (specifier-type `(integer ,(or lo '*) ,(or hi '*))))))
    
    2057 2062
     
    
    2058 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
    ... ... @@ -443,3 +443,64 @@
    443 443
     		    (write (read-from-string "`(,@vars ,@vars)")
    
    444 444
     			   :pretty t
    
    445 445
     			   :stream s)))))
    
    446
    +
    
    447
    +(define-test issue.59
    
    448
    +  (:tag :issues)
    
    449
    +  (let ((f (compile nil #'(lambda (z)
    
    450
    +			    (declare (type (double-float -2d0 0d0) z))
    
    451
    +			    (nth-value 2 (decode-float z))))))
    
    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