Raymond Toy pushed to branch master at cmucl / cmucl

Commits:

3 changed files:

Changes:

  • src/code/float.lisp
    ... ... @@ -1137,7 +1137,8 @@
    1137 1137
     			      (floatit (ash bits -1))
    
    1138 1138
     			    #+nil
    
    1139 1139
     			    (progn
    
    1140
    -			      (format t "1: f0, f1 = ~A ~A~%" f0 f1)
    
    1140
    +                              (format t "x = ~A~%" x)
    
    1141
    +			      (format t "1: f0, f1 = ~A~%" f0)
    
    1141 1142
     			      (format t "   scale = ~A~%" (1+ scale)))
    
    1142 1143
     			    
    
    1143 1144
     			    (scale-float f0 (1+ scale))))
    
    ... ... @@ -1146,14 +1147,30 @@
    1146 1147
     			      (floatit bits)
    
    1147 1148
     			    #+nil
    
    1148 1149
     			    (progn
    
    1149
    -			      (format t "2: f0, f1 = ~A ~A~%" f0 f1)
    
    1150
    +			      (format t "2: f0, f1 = ~A~%" f0)
    
    1150 1151
     			      (format t "   scale = ~A~%" scale)
    
    1151
    -			      (format t "scale-float f0 = ~A~%" (scale-float f0 scale))
    
    1152
    -			      (when f1
    
    1153
    -				(format t "scale-float f1 = ~A~%"
    
    1154
    -					(scale-float f1 (- scale 53)))))
    
    1155
    -			    
    
    1156
    -				(scale-float f0 scale))))))
    
    1152
    +			      (format t "scale-float f0 = ~A~%" (scale-float f0 scale)))
    
    1153
    +                            (let ((min-exponent
    
    1154
    +                                    ;; Compute the min (unbiased) exponent
    
    1155
    +                                    (ecase format
    
    1156
    +                                      (single-float
    
    1157
    +                                       (- vm:single-float-normal-exponent-min
    
    1158
    +                                          vm:single-float-bias
    
    1159
    +                                          vm:single-float-digits))
    
    1160
    +                                      (double-float
    
    1161
    +                                       (- vm:double-float-normal-exponent-min
    
    1162
    +                                          vm:double-float-bias
    
    1163
    +                                          vm:double-float-digits)))))
    
    1164
    +                              ;; F0 is always between 0.5 and 1.  If
    
    1165
    +                              ;; SCALE is the min exponent, we have a
    
    1166
    +                              ;; denormal number just less than the
    
    1167
    +                              ;; least-positive float.  We want to
    
    1168
    +                              ;; return the least-positive-float so
    
    1169
    +                              ;; multiply F0 by 2 (without adjusting
    
    1170
    +                              ;; SCALE) to get the nearest float.
    
    1171
    +                              (if (= scale min-exponent)
    
    1172
    +                                  (scale-float (* 2 f0) scale)
    
    1173
    +			          (scale-float f0 scale))))))))
    
    1157 1174
     	       (floatit (bits)
    
    1158 1175
     		 (let ((sign (if plusp 0 1)))
    
    1159 1176
     		   (case format
    

  • src/general-info/release-21f.md
    ... ... @@ -44,6 +44,8 @@ public domain.
    44 44
         * ~~#266~~ Support "~user" in namestrings
    
    45 45
         * ~~#271~~ Update ASDF to 3.3.7
    
    46 46
         * ~~#272~~ Move scavenge code for static vectors to its own function
    
    47
    +    * ~~#277~~ `float-ratio-float` returns least postive float for
    
    48
    +      ratios closer to that than zero.
    
    47 49
       * Other changes:
    
    48 50
       * Improvements to the PCL implementation of CLOS:
    
    49 51
       * Changes to building procedure:
    

  • tests/float.lisp
    ... ... @@ -136,5 +136,49 @@
    136 136
         (ext:with-float-traps-masked (:overflow)
    
    137 137
           (* 100 most-negative-double-float)))))
    
    138 138
     
    
    139
    -  
    
    140
    -   
    \ No newline at end of file
    139
    +(define-test float-ratio.single
    
    140
    +    (:tag :issues)
    
    141
    +  ;; least-positive-single-float is 1.4012985e-45.  Let's test with
    
    142
    +  ;; some rationals from 7/10*10^-45 to 1.41*10^-45 to make sure they
    
    143
    +  ;; return 0 or least-positive-single-float
    
    144
    +  (let ((expo (expt 10 -45)))
    
    145
    +    ;; Need to make sure underflows are masked.
    
    146
    +    (kernel::with-float-traps-masked (:underflow)
    
    147
    +      ;; 7/10*10^-45 is just under halfway between 0 and least-positive,
    
    148
    +      ;; so the answer is 0.
    
    149
    +      (assert-equal 0f0 (kernel::float-ratio-float (* 7/10 expo) 'single-float))
    
    150
    +
    
    151
    +      ;; These are all more than half way to
    
    152
    +      ;; least-positive-single-float, so they should return that.
    
    153
    +      (assert-equal least-positive-single-float
    
    154
    +                    (kernel::float-ratio-float (* 8/10 expo) 'single-float))
    
    155
    +      (assert-equal least-positive-single-float
    
    156
    +                    (kernel::float-ratio-float (* 1 expo) 'single-float))
    
    157
    +      (assert-equal least-positive-single-float
    
    158
    +                    (kernel::float-ratio-float (* 14/10 expo) 'single-float))
    
    159
    +      (assert-equal least-positive-single-float
    
    160
    +                    (kernel::float-ratio-float (* 2 expo) 'single-float)))))
    
    161
    +
    
    162
    +(define-test float-ratio.double
    
    163
    +    (:tag :issues)
    
    164
    +  ;; least-positive-double-float is 4.9406564584124654d-324.  Let's
    
    165
    +  ;; test with some rationals from about 2*10^-324 to 4.94*10^-324 to make
    
    166
    +  ;; sure they return 0 or least-positive-double-float
    
    167
    +  (let ((expo (expt 10 -324)))
    
    168
    +    ;; Need to make sure underflows are masked.
    
    169
    +    (kernel::with-float-traps-masked (:underflow)
    
    170
    +      ;; 247/100*10^-324 is just under halfway between 0 and least-positive,
    
    171
    +      ;; so the answer is 0.
    
    172
    +      (assert-equal 0d0 (kernel::float-ratio-float (* 247/100 expo) 'double-float))
    
    173
    +
    
    174
    +      ;; These are all more than half way to
    
    175
    +      ;; least-positive-double-float, so they should return that.
    
    176
    +      (assert-equal least-positive-double-float
    
    177
    +                    (kernel::float-ratio-float (* 248/100 expo) 'double-float))
    
    178
    +      (assert-equal least-positive-double-float
    
    179
    +                    (kernel::float-ratio-float (* 4 expo) 'double-float))
    
    180
    +      (assert-equal least-positive-double-float
    
    181
    +                    (kernel::float-ratio-float (* 494/100 expo) 'double-float))
    
    182
    +      (assert-equal least-positive-double-float
    
    183
    +                    (kernel::float-ratio-float (* 988/100 expo) 'double-float)))))
    
    184
    +