Raymond Toy pushed to branch issue-274-make-float-of-huge-numbers at cmucl / cmucl

Commits:

1 changed file:

Changes:

  • src/code/reader.lisp
    ... ... @@ -1833,25 +1833,31 @@ the end of the stream."
    1833 1833
       ;; super accurate with the limits.  The rest of the code will handle
    
    1834 1834
       ;; it correctly, even if we're too small or too large.
    
    1835 1835
       (unless (zerop number)
    
    1836
    -    (let ((log2-num (+ (kernel::log2 (float (/ number divisor) 1d0))
    
    1837
    -                       (* exponent #.(kernel::log2 10d0)))))
    
    1838
    -      (multiple-value-bind (log2-low log2-high)
    
    1839
    -          (ecase float-format
    
    1840
    -            ((short-float single-float)
    
    1841
    -             ;; Single-float exponents range is -149 to 127
    
    1842
    -             (values (* 2 -149) (* 2 127)))
    
    1843
    -            ((double-float long-float
    
    1844
    -                           #+double-double kernel:double-double-float)
    
    1845
    -             ;; Double-float exponent range is -1074 to -1023
    
    1846
    -             (values (* 2 -1074) (* 2 1023))))
    
    1847
    -        (when (< log2-num log2-low)
    
    1848
    -          ;; If the number is too small, just return 0.
    
    1849
    -          (return-from make-float-aux (coerce 0 float-format)))
    
    1836
    +    (flet ((fast-log2 (n)
    
    1837
    +             ;;  For an integer, the integer-length is close enough to
    
    1838
    +             ;;  the log2 of the number.
    
    1839
    +             (integer-length n)))
    
    1840
    +      ;; log2(x) = exponent*log2(10) + log2(number)-log2(divisor)
    
    1841
    +      (let ((log2-num (+ (* exponent #.(kernel::log2 10d0))
    
    1842
    +                         (fast-log2 number)
    
    1843
    +                         (- (fast-log2 divisor)))))
    
    1844
    +        (multiple-value-bind (log2-low log2-high)
    
    1845
    +            (ecase float-format
    
    1846
    +              ((short-float single-float)
    
    1847
    +               ;; Single-float exponents range is -149 to 127
    
    1848
    +               (values (* 2 -149) (* 2 127)))
    
    1849
    +              ((double-float long-float
    
    1850
    +                             #+double-double kernel:double-double-float)
    
    1851
    +               ;; Double-float exponent range is -1074 to -1023
    
    1852
    +               (values (* 2 -1074) (* 2 1023))))
    
    1853
    +          (when (< log2-num log2-low)
    
    1854
    +            ;; If the number is too small, just return 0.
    
    1855
    +            (return-from make-float-aux (coerce 0 float-format)))
    
    1850 1856
           
    
    1851
    -        (when (> log2-num log2-high)
    
    1852
    -          ;; The numbe is definitely too large to fit.  Signal an error.
    
    1853
    -          (%reader-error stream _"Number not representable as a ~S: ~S"
    
    1854
    -			 float-format (read-buffer-to-string))))))
    
    1857
    +          (when (> log2-num log2-high)
    
    1858
    +            ;; The numbe is definitely too large to fit.  Signal an error.
    
    1859
    +            (%reader-error stream _"Number not representable as a ~S: ~S"
    
    1860
    +			   float-format (read-buffer-to-string)))))))
    
    1855 1861
     
    
    1856 1862
       ;; Otherwise the number might fit, so we carefully compute the result
    
    1857 1863
       (handler-case