Raymond Toy pushed to branch rtoy-ryu-printf at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/print.lisp
    ... ... @@ -2096,7 +2096,10 @@ radix-R. If you have a power-list then pass it in as PL."
    2096 2096
     			     raw-string))
    
    2097 2097
     	 (mantissa (subseq raw-string 0 e-pos))
    
    2098 2098
     	 (exp (parse-integer raw-string :start (1+ e-pos))))
    
    2099
    -    (values mantissa exp)))
    
    2099
    +    ;; The exponent from a double-float is in the range of [-324,
    
    2100
    +    ;; 308].  Just declare the exponent as a (signed-byte 11).
    
    2101
    +    (values mantissa
    
    2102
    +	    (truly-the (signed-byte 11) exp))))
    
    2100 2103
     
    
    2101 2104
     (defun compute-d-for-width (w e k actual-exp is-negative-p at-sign-p)
    
    2102 2105
       ;; Find the largest d (precision) value that fits in width W given
    
    ... ... @@ -2138,6 +2141,9 @@ radix-R. If you have a power-list then pass it in as PL."
    2138 2141
     
    
    2139 2142
     (defun compute-exp-output-length (mantissa actual-exp k e is-negative-p at-sign-p
    
    2140 2143
     				  drop-leading-zero-p)
    
    2144
    +  (declare (type simple-string mantissa)
    
    2145
    +	   (fixnum actual-exp k)
    
    2146
    +	   (type (or null fixnum) e))
    
    2141 2147
       ;; Compute length of the ~E result with the given parameters, but
    
    2142 2148
       ;; don't build the string.  MANTISSA is "d[.dddd]" from d2exp or d2s.
    
    2143 2149
       ;; ACTUAL-EXP is the exponent with scaling factor applied.  If
    
    ... ... @@ -2154,19 +2160,20 @@ radix-R. If you have a power-list then pass it in as PL."
    2154 2160
                  ((plusp k)
    
    2155 2161
                   (cond
    
    2156 2162
                     ((> raw-digits k)
    
    2157
    -                 (1+ raw-digits))                     ; "D.DDDD"
    
    2163
    +                 (1+ raw-digits))	; "D.DDDD"
    
    2158 2164
                     ((and (= k 1) (= raw-digits 1))
    
    2159
    -                 3)                                   ; "D.0" forced
    
    2165
    +                 3)			; "D.0" forced
    
    2160 2166
                     (t
    
    2161
    -                 (max raw-digits k))))                ; "DDDD"
    
    2167
    +                 (max raw-digits k))))	; "DDDD"
    
    2162 2168
                  (t
    
    2163 2169
                   ;; "0.000DDD" or ".000DDD"
    
    2164 2170
                   (+ (if drop-leading-zero-p 0 1)
    
    2165
    -                 1                                    ; the dot
    
    2166
    -                 (- k)                                ; leading zeros after the dot
    
    2171
    +                 1			; the dot
    
    2172
    +                 (- k)			; leading zeros after the dot
    
    2167 2173
                      raw-digits)))))
    
    2168 2174
         ;; +2 for the exponent marker and sign
    
    2169
    -    (+ sign-len mantissa-len exp-digits 2)))
    
    2175
    +    (the (and unsigned-byte fixnum)
    
    2176
    +		 (+ sign-len mantissa-len exp-digits 2))))
    
    2170 2177
     
    
    2171 2178
     (defun scale-mantissa (stream mantissa-text k drop-leading-zero-p)
    
    2172 2179
       "Write MANTISSA-TEXT to STREAM, shifting the decimal point so that
    
    ... ... @@ -2240,7 +2247,9 @@ radix-R. If you have a power-list then pass it in as PL."
    2240 2247
     (defun pad-overflow (stream field-len w overflowchar padchar field-writer)
    
    2241 2248
       "Apply width/pad/overflow rules.  FIELD-WRITER is a thunk of zero
    
    2242 2249
        arguments that writes the field characters to STREAM."
    
    2243
    -  (declare (function field-writer))
    
    2250
    +  (declare (fixnum field-len)
    
    2251
    +	   (type (or null fixnum) w)
    
    2252
    +	   (function field-writer))
    
    2244 2253
       (cond
    
    2245 2254
         ((null w)
    
    2246 2255
          (funcall field-writer))
    
    ... ... @@ -2267,7 +2276,7 @@ radix-R. If you have a power-list then pass it in as PL."
    2267 2276
     	     (abs value)))
    
    2268 2277
         (single-float
    
    2269 2278
          (values (minusp (float-sign value))
    
    2270
    -	     (abs (float (value 1d0)))))))
    
    2279
    +	     (abs (float value 1d0))))))
    
    2271 2280
          
    
    2272 2281
     (defun d2exp-precision (d k)
    
    2273 2282
       ;; Compute precision for d2exp when CL requests D digits and the
    
    ... ... @@ -2297,8 +2306,6 @@ radix-R. If you have a power-list then pass it in as PL."
    2297 2306
              (exp-digits (count-decimal-digits exp-abs))
    
    2298 2307
              (exp-width (max (or e 1)
    
    2299 2308
     			 exp-digits))
    
    2300
    -         (sign-len (if (or is-negative-p at-sign-p)
    
    2301
    -		       1 0))
    
    2302 2309
              ;; Full output length: sign + reshaped + marker + exp-sign +
    
    2303 2310
              ;; exp-width.  compute-exp-output-length gives reshape + exp
    
    2304 2311
              ;; body (marker + exp-sign + max(e, exp-digits)), but it also
    
    ... ... @@ -2364,23 +2371,33 @@ radix-R. If you have a power-list then pass it in as PL."
    2364 2371
                                            nil))))))))))))
    
    2365 2372
     
    
    2366 2373
     ;;; Ryu ~F
    
    2367
    -(defun format-f-fixed (stream abs-value is-negative-p w d
    
    2374
    +(defun format-f-fixed (stream value w d
    
    2368 2375
                            overflowchar padchar at-sign-p)
    
    2369
    -  (declare (double-float abs-value))
    
    2370
    -  (let* ((raw-string (d2fixed abs-value d))
    
    2371
    -         (raw-len    (length raw-string))
    
    2372
    -         (sign-len   (if (or is-negative-p at-sign-p) 1 0))
    
    2373
    -         (need-dot   (zerop d))
    
    2374
    -         (field-len  (+ sign-len raw-len (if need-dot 1 0))))
    
    2375
    -    (flet ((write-field ()
    
    2376
    -             (cond (is-negative-p (write-char #\- stream))
    
    2377
    -                   (at-sign-p     (write-char #\+ stream)))
    
    2378
    -             (write-string raw-string stream)
    
    2379
    -             (when need-dot (write-char #\. stream))))
    
    2380
    -      (declare (dynamic-extent #'write-field))
    
    2381
    -      (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    2382
    -	       
    
    2376
    +  (declare (type (or single-float double-float) value))
    
    2377
    +  (multiple-value-bind (is-negative-p abs-value)
    
    2378
    +      (get-sign-and-absolute-value value)
    
    2379
    +    (let* ((raw-string (d2fixed abs-value d))
    
    2380
    +           (raw-len    (length raw-string))
    
    2381
    +           (sign-len   (if (or is-negative-p at-sign-p) 1 0))
    
    2382
    +           (need-dot   (zerop d))
    
    2383
    +           (field-len  (+ sign-len raw-len (if need-dot 1 0))))
    
    2384
    +      (flet ((write-field ()
    
    2385
    +               (cond (is-negative-p (write-char #\- stream))
    
    2386
    +                     (at-sign-p     (write-char #\+ stream)))
    
    2387
    +               (write-string raw-string stream)
    
    2388
    +               (when need-dot (write-char #\. stream))))
    
    2389
    +	(declare (dynamic-extent #'write-field))
    
    2390
    +	(pad-overflow stream field-len w overflowchar padchar #'write-field)))))
    
    2391
    +
    
    2383 2392
     (defun reshape-fixed-length (digit-count exponent)
    
    2393
    +  ;; DIGIT-COUNT is the number of digits returned by d2s/f2s.  That no
    
    2394
    +  ;; more than 20.  EXPONENT is teh power of 10 for a double-float.  A
    
    2395
    +  ;; signed-byte 10 is large enough to hold this.
    
    2396
    +  ;;
    
    2397
    +  ;; We don't need to be super-precise here; we just need to be close
    
    2398
    +  ;; enough so as not to use bignums.
    
    2399
    +  (declare (type (integer 1 20) digit-count)
    
    2400
    +	   (type (signed-byte 10) exponent))
    
    2384 2401
       (let ((k (1+ exponent)))
    
    2385 2402
         (cond ((zerop exponent)
    
    2386 2403
     	   ;; Fast path
    
    ... ... @@ -2399,6 +2416,8 @@ radix-R. If you have a power-list then pass it in as PL."
    2399 2416
     
    
    2400 2417
     (defun emit-shortest (stream mantissa exponent is-negative-p w
    
    2401 2418
                           overflowchar padchar at-sign-p)
    
    2419
    +  (declare (type simple-string mantissa)
    
    2420
    +	   (type (signed-byte 10) exponent))
    
    2402 2421
       (let* ((has-dot (find #\. mantissa))
    
    2403 2422
     	 ;; Number of digits, not including the decimal point.
    
    2404 2423
     	 (digit-count (- (length mantissa)
    
    ... ... @@ -2415,53 +2434,52 @@ radix-R. If you have a power-list then pass it in as PL."
    2415 2434
           (declare (dynamic-extent #'write-field))
    
    2416 2435
           (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    2417 2436
     	 
    
    2418
    -(defun format-f-free (stream value is-negative-p w
    
    2437
    +(defun format-f-free (stream value w
    
    2419 2438
                           overflowchar padchar at-sign-p)
    
    2420 2439
       (declare (type (or single-float double-float) value))
    
    2421
    -  (multiple-value-bind (mantissa exponent)
    
    2422
    -      (parsed-exp-form (float-to-string value))
    
    2423
    -    (let* ((has-dot     (find #\. mantissa))
    
    2424
    -           (digit-count (if has-dot (1- (length mantissa)) (length mantissa)))
    
    2425
    -           (int-len     (max 1 (1+ exponent)))
    
    2426
    -           (shortest-d  (max 0 (- digit-count 1 exponent)))
    
    2427
    -           (sign-len    (if (or is-negative-p at-sign-p) 1 0))
    
    2428
    -           (d-fit       (and w (- w sign-len int-len 1))))
    
    2429
    -      (cond
    
    2430
    -        ((or (null w) (>= d-fit shortest-d))
    
    2431
    -         (emit-shortest stream mantissa exponent is-negative-p w
    
    2432
    -                        overflowchar padchar at-sign-p))
    
    2433
    -        ((minusp d-fit)
    
    2434
    -         (cond (overflowchar
    
    2435
    -                (loop repeat w do (write-char overflowchar stream)))
    
    2436
    -               (t
    
    2437
    -                (emit-shortest stream mantissa exponent is-negative-p w
    
    2438
    -                               overflowchar padchar at-sign-p))))
    
    2439
    -        (t
    
    2440
    -	 (multiple-value-bind (is-negative-p abs-value)
    
    2441
    -	     (get-sign-and-absolute-value value)
    
    2442
    -           (format-f-fixed stream abs-value is-negative-p w d-fit
    
    2440
    +  (multiple-value-bind (is-negative-p abs-value)
    
    2441
    +      (get-sign-and-absolute-value value)
    
    2442
    +    (declare (ignore abs-value))
    
    2443
    +    (multiple-value-bind (mantissa exponent)
    
    2444
    +	(parsed-exp-form (float-to-string value))
    
    2445
    +      (let* ((has-dot     (find #\. mantissa))
    
    2446
    +             (digit-count (if has-dot (1- (length mantissa)) (length mantissa)))
    
    2447
    +             (int-len     (max 1 (1+ exponent)))
    
    2448
    +             (shortest-d  (max 0 (- digit-count 1 exponent)))
    
    2449
    +             (sign-len    (if (or is-negative-p at-sign-p) 1 0))
    
    2450
    +             (d-fit       (and w (- w sign-len int-len 1))))
    
    2451
    +	(cond
    
    2452
    +          ((or (null w) (>= d-fit shortest-d))
    
    2453
    +           (emit-shortest stream mantissa exponent is-negative-p w
    
    2454
    +                          overflowchar padchar at-sign-p))
    
    2455
    +          ((minusp d-fit)
    
    2456
    +           (cond (overflowchar
    
    2457
    +                  (loop repeat w do (write-char overflowchar stream)))
    
    2458
    +		 (t
    
    2459
    +                  (emit-shortest stream mantissa exponent is-negative-p w
    
    2460
    +				 overflowchar padchar at-sign-p))))
    
    2461
    +          (t
    
    2462
    +           (format-f-fixed stream value w d-fit
    
    2443 2463
                                overflowchar padchar at-sign-p)))))))
    
    2444 2464
     
    
    2445 2465
     (defun format-f (value w d k overflowchar padchar at-sign-p)
    
    2446 2466
       (declare (type (or single-float double-float) value)
    
    2447 2467
     	   (fixnum k)
    
    2448 2468
     	   (type (or null (and unsigned-byte fixnum)) w d))
    
    2449
    -  (multiple-value-bind (is-negative-p abs-value)
    
    2450
    -      (get-sign-and-absolute-value value)
    
    2451
    -    (with-output-to-string (s)
    
    2452
    -      (cond ((not (zerop k))
    
    2453
    -	     ;;  Complex case that doesn't fit with what d2s and d2fixed
    
    2454
    -	     ;;  returns.  Especially when d+k is negative so that some
    
    2455
    -	     ;;  digits are shifted right past the desired precision.
    
    2456
    -	     ;;  We'd have to round the result.  Just use our existing
    
    2457
    -	     ;;  code to handle this case with the correct rounding.
    
    2458
    -	     (format::format-fixed-aux s value w d k overflowchar padchar at-sign-p))
    
    2459
    -	    (d
    
    2460
    -	     (format-f-fixed s abs-value is-negative-p w d overflowchar padchar at-sign-p))
    
    2461
    -	    (t
    
    2462
    -	     ;; No d, so use d2s to get the shortest digits; convert by
    
    2463
    -	     ;; placing the decimal poin at the right spot.
    
    2464
    -	     (format-f-free s value is-negative-p  w overflowchar padchar at-sign-p))))))
    
    2469
    +  (with-output-to-string (s)
    
    2470
    +    (cond ((not (zerop k))
    
    2471
    +	   ;;  Complex case that doesn't fit with what d2s and d2fixed
    
    2472
    +	   ;;  returns.  Especially when d+k is negative so that some
    
    2473
    +	   ;;  digits are shifted right past the desired precision.
    
    2474
    +	   ;;  We'd have to round the result.  Just use our existing
    
    2475
    +	   ;;  code to handle this case with the correct rounding.
    
    2476
    +	   (format::format-fixed-aux s value w d k overflowchar padchar at-sign-p))
    
    2477
    +	  (d
    
    2478
    +	   (format-f-fixed s value w d overflowchar padchar at-sign-p))
    
    2479
    +	  (t
    
    2480
    +	   ;; No d, so use d2s to get the shortest digits; convert by
    
    2481
    +	   ;; placing the decimal poin at the right spot.
    
    2482
    +	   (format-f-free s value  w overflowchar padchar at-sign-p)))))
    
    2465 2483
     
    
    2466 2484
     ;;; Ryu ~G
    
    2467 2485
     (defun format-g (value w d e k overflowchar padchar exponentchar at-sign-p)
    
    ... ... @@ -2470,7 +2488,9 @@ radix-R. If you have a power-list then pass it in as PL."
    2470 2488
     	   (type (or null (and unsigned-byte fixnum)) w d e))
    
    2471 2489
       (multiple-value-bind (mantissa exponent)
    
    2472 2490
           (parsed-exp-form (float-to-string value))
    
    2473
    -    (let* ((digit-count (length (remove #\. mantissa)))
    
    2491
    +    (let* ((digit-count (- (length mantissa)
    
    2492
    +			   (if (find #\. mantissa)
    
    2493
    +			       1 0)))
    
    2474 2494
     	   (n (1+ exponent))
    
    2475 2495
     	   (effective-d (or d (max digit-count (min n 7))))
    
    2476 2496
     	   (ee (if e (+ e 2) 4))
    

  • src/i18n/locale/cmucl.pot
    No preview for this file type