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

Commits:

2 changed files:

Changes:

  • src/code/print.lisp
    ... ... @@ -2107,36 +2107,34 @@ radix-R. If you have a power-list then pass it in as PL."
    2107 2107
             ((< n 100) 2)
    
    2108 2108
             (t         3)))
    
    2109 2109
     
    
    2110
    -(defun compute-exp-output-length (mantissa actual-exp k e is-negative-p at-sign-p leading-zero-p)
    
    2110
    +(defun compute-exp-output-length (mantissa actual-exp k e is-negative-p at-sign-p drop-leading-zero-p)
    
    2111 2111
       ;; Compute length of the ~E result with the given parameters, but
    
    2112
    -  ;; don't build the string.  MANTISSA is "d.dddEee" from d2exp or
    
    2113
    -  ;; d2s.  ACTUAL-EXP is the exponent with scaling factor applied.  If
    
    2114
    -  ;; LEADING-ZERO-P is not NIL, the leading "0" will be kept when K <=
    
    2115
    -  ;; 0.  Otherwise it's ignored.
    
    2112
    +  ;; don't build the string.  MANTISSA is "d[.dddd]" from d2exp or d2s.
    
    2113
    +  ;; ACTUAL-EXP is the exponent with scaling factor applied.  If
    
    2114
    +  ;; DROP-LEADING-ZERO-P is non-NIL, the leading "0" before the dot
    
    2115
    +  ;; (in the K <= 0 form) is omitted from the length.
    
    2116 2116
       (let* ((sign-len (if (or is-negative-p at-sign-p) 1 0))
    
    2117
    -	 (exp-digits (max (or e 1)
    
    2118
    -			  #+nil
    
    2119
    -			  (length (princ-to-string (abs actual-exp)))
    
    2120
    -			  (count-decimal-digits (abs actual-exp))))
    
    2121
    -	 (dotp (find #\. mantissa))
    
    2122
    -	 (raw-digits (let ((len (length mantissa)))
    
    2123
    -		       (if dotp (1- len) len)))
    
    2124
    -	 (mantissa-len
    
    2125
    -	   (cond
    
    2126
    -	     ((plusp k)
    
    2127
    -	      ;; k digits before, raw-digits - k after the dot.  If
    
    2128
    -	      ;; raw-digitis <= k no dot and pad with zeroes before.
    
    2129
    -	      (if (> raw-digits k)
    
    2130
    -		  ;; "d.dddd" so raw-dits with dot.
    
    2131
    -		  (1+ raw-digits)
    
    2132
    -		  ;; "dddd" no dot, possibly padded.
    
    2133
    -		  (max raw-digits k)))
    
    2134
    -	     (t
    
    2135
    -	      ;; "0.000ddd" or ".000ddd"
    
    2136
    -	      (+ (if leading-zero-p 1 0)
    
    2137
    -		 1
    
    2138
    -		 (- k)
    
    2139
    -		 raw-digits)))))
    
    2117
    +         (exp-digits (max (or e 1)
    
    2118
    +                          (count-decimal-digits (abs actual-exp))))
    
    2119
    +         (dotp (find #\. mantissa))
    
    2120
    +         (raw-digits (let ((len (length mantissa)))
    
    2121
    +                       (if dotp (1- len) len)))
    
    2122
    +         (mantissa-len
    
    2123
    +           (cond
    
    2124
    +             ((plusp k)
    
    2125
    +              (cond
    
    2126
    +                ((> raw-digits k)
    
    2127
    +                 (1+ raw-digits))                     ; "D.DDDD"
    
    2128
    +                ((and (= k 1) (= raw-digits 1))
    
    2129
    +                 3)                                   ; "D.0" forced
    
    2130
    +                (t
    
    2131
    +                 (max raw-digits k))))                ; "DDDD"
    
    2132
    +             (t
    
    2133
    +              ;; "0.000DDD" or ".000DDD"
    
    2134
    +              (+ (if drop-leading-zero-p 0 1)
    
    2135
    +                 1                                    ; the dot
    
    2136
    +                 (- k)                                ; leading zeros after the dot
    
    2137
    +                 raw-digits)))))
    
    2140 2138
         ;; +2 for the exponent marker and sign
    
    2141 2139
         (+ sign-len mantissa-len exp-digits 2)))
    
    2142 2140
     
    
    ... ... @@ -2279,10 +2277,6 @@ radix-R. If you have a power-list then pass it in as PL."
    2279 2277
            ;; Finish with ".0"
    
    2280 2278
            (write-string ".0" stream)))))
    
    2281 2279
     
    
    2282
    -(defun reshape-format-e (mantissa-text k drop-leading-zero-p)
    
    2283
    -  (with-output-to-string (s)
    
    2284
    -    (scale-mantissa s mantissa-text k drop-leading-zero-p)))
    
    2285
    -
    
    2286 2280
     (defun d2exp-precision (d k)
    
    2287 2281
       ;; Compute precision for d2exp when CL requests D digits and the
    
    2288 2282
       ;; scale factor is K."
    
    ... ... @@ -2298,6 +2292,7 @@ radix-R. If you have a power-list then pass it in as PL."
    2298 2292
     	 ;; d - |k| - 1 digits after the decimal point.
    
    2299 2293
     	 (max (+ d k -1) 0))))
    
    2300 2294
     		  
    
    2295
    +#+nil
    
    2301 2296
     (defun format-e-string (mantissa exponent is-negative-p w e k
    
    2302 2297
                             overflowchar padchar exponentchar at-sign-p
    
    2303 2298
                             drop-leading-zero-p)
    
    ... ... @@ -2347,6 +2342,44 @@ radix-R. If you have a power-list then pass it in as PL."
    2347 2342
                  (loop repeat (- w field-len) do (write-char pad-char s))
    
    2348 2343
                  (write-field s))))))))
    
    2349 2344
     
    
    2345
    +(defun format-e-string (stream mantissa exponent is-negative-p w e k
    
    2346
    +                        overflowchar padchar exponentchar at-sign-p
    
    2347
    +                        drop-leading-zero-p)
    
    2348
    +  (declare (type simple-string mantissa)
    
    2349
    +           (fixnum exponent k))
    
    2350
    +  (let* ((shown-exp (- exponent (1- k)))
    
    2351
    +         (exp-sign (if (minusp shown-exp)
    
    2352
    +		       #\- #\+))
    
    2353
    +         (exp-abs (abs shown-exp))
    
    2354
    +         (exp-marker (or exponentchar #\d))
    
    2355
    +         (exp-digits (count-decimal-digits exp-abs))
    
    2356
    +         (exp-width (max (or e 1)
    
    2357
    +			 exp-digits))
    
    2358
    +         (sign-len (if (or is-negative-p at-sign-p)
    
    2359
    +		       1 0))
    
    2360
    +         ;; Full output length: sign + reshaped + marker + exp-sign +
    
    2361
    +         ;; exp-width.  compute-exp-output-length gives reshape + exp
    
    2362
    +         ;; body (marker + exp-sign + max(e, exp-digits)), but it also
    
    2363
    +         ;; includes sign, so use it directly.  Wait, it doesn't
    
    2364
    +         ;; account for drop-leading-zero, so we use it carefully.
    
    2365
    +         (field-len (compute-exp-output-length mantissa shown-exp k e
    
    2366
    +                                               is-negative-p at-sign-p
    
    2367
    +                                               drop-leading-zero-p)))
    
    2368
    +    (flet ((write-field ()
    
    2369
    +             (cond (is-negative-p
    
    2370
    +		    (write-char #\- stream))
    
    2371
    +                   (at-sign-p
    
    2372
    +		    (write-char #\+ stream)))
    
    2373
    +             (scale-mantissa stream mantissa k drop-leading-zero-p)
    
    2374
    +             (write-char exp-marker stream)
    
    2375
    +             (write-char exp-sign stream)
    
    2376
    +             (loop repeat (- exp-width exp-digits)
    
    2377
    +		   do (write-char #\0 stream))
    
    2378
    +             (princ exp-abs stream)))
    
    2379
    +      (declare (dynamic-extent #'write-field))
    
    2380
    +      (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    2381
    +
    
    2382
    +#+nil
    
    2350 2383
     (defun format-e (value w d e k overflowchar padchar exponentchar at-sign-p)
    
    2351 2384
       (declare (double-float value)
    
    2352 2385
     	   (fixnum k)
    
    ... ... @@ -2404,6 +2437,46 @@ radix-R. If you have a power-list then pass it in as PL."
    2404 2437
     				     w e k overflowchar padchar exponentchar at-sign-p
    
    2405 2438
     				     nil)))))))))))
    
    2406 2439
     
    
    2440
    +(defun format-e (value w d e k overflowchar padchar exponentchar at-sign-p)
    
    2441
    +  (declare (double-float value)
    
    2442
    +           (fixnum k)
    
    2443
    +           (type (or null (and unsigned-byte fixnum)) w d e)
    
    2444
    +           (optimize (speed 3)))
    
    2445
    +  (let* ((is-negative-p (minusp (float-sign value)))
    
    2446
    +         (abs-value (abs value)))
    
    2447
    +    (with-output-to-string (stream)
    
    2448
    +      (cond
    
    2449
    +        (d
    
    2450
    +         (multiple-value-bind (mantissa exponent)
    
    2451
    +             (parsed-exp-form (d2exp abs-value (d2exp-precision d k)))
    
    2452
    +           (format-e-string stream mantissa exponent is-negative-p
    
    2453
    +                            w e k overflowchar padchar exponentchar at-sign-p nil)))
    
    2454
    +        (t
    
    2455
    +         (multiple-value-bind (mantissa exponent)
    
    2456
    +             (parsed-exp-form (d2s abs-value))
    
    2457
    +           (let* ((actual-exp (- exponent (1- k)))
    
    2458
    +                  (full-len (compute-exp-output-length mantissa actual-exp k e
    
    2459
    +                                                       is-negative-p at-sign-p
    
    2460
    +                                                       nil)))
    
    2461
    +             (cond
    
    2462
    +               ((or (null w)
    
    2463
    +		    (<= full-len w))
    
    2464
    +                (format-e-string stream mantissa exponent is-negative-p
    
    2465
    +                                 w e k overflowchar padchar exponentchar at-sign-p
    
    2466
    +                                 (not (plusp k))))
    
    2467
    +               (t
    
    2468
    +                (let* ((d-fit (compute-d-for-width w e k actual-exp is-negative-p at-sign-p))
    
    2469
    +                       (drop-zero-p (and d-fit (<= k 0))))
    
    2470
    +                  (if d-fit
    
    2471
    +                      (multiple-value-bind (mantissa exponent)
    
    2472
    +                          (parsed-exp-form (d2exp abs-value (d2exp-precision d-fit k)))
    
    2473
    +                        (format-e-string stream mantissa exponent is-negative-p
    
    2474
    +                                         w e k overflowchar padchar exponentchar at-sign-p
    
    2475
    +                                         drop-zero-p))
    
    2476
    +                      (format-e-string stream mantissa exponent is-negative-p
    
    2477
    +                                       w e k overflowchar padchar exponentchar at-sign-p
    
    2478
    +                                       nil))))))))))))
    
    2479
    +
    
    2407 2480
     ;;; Ryu ~F
    
    2408 2481
     #+nil
    
    2409 2482
     (defun format-f-fixed (stream abs-value is-negative-p w d overflowchar padchar at-sign-p)
    
    ... ... @@ -2457,13 +2530,6 @@ radix-R. If you have a power-list then pass it in as PL."
    2457 2530
           (declare (dynamic-extent #'writ-field))
    
    2458 2531
           (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    2459 2532
     	       
    
    2460
    -(defun reshape-fixed (stream mantissa-text exponent)
    
    2461
    -  "Adjust MANTISSA-TEXT is scaled exactly by 10^{EXPONENT} by moving the
    
    2462
    -  decimal point.  MANTISSA-TEXT is of the form 'd[.dddd]' from d2exp
    
    2463
    -  or d2s.  The scaled value is written to STREAM."
    
    2464
    -  (scale-mantissa stream mantissa-text (1+ exponent) nil))
    
    2465
    -    
    
    2466
    -
    
    2467 2533
     (defun reshape-fixed-length (digit-count exponent)
    
    2468 2534
       (let ((k (1+ exponent)))
    
    2469 2535
         (cond ((zerop exponent)
    
    ... ... @@ -2491,9 +2557,11 @@ radix-R. If you have a power-list then pass it in as PL."
    2491 2557
     	 (reshaped-len (reshape-fixed-length digit-count exponent))
    
    2492 2558
              (field-len (+ sign-len reshaped-len)))
    
    2493 2559
         (flet ((write-field ()
    
    2494
    -             (cond (is-negative-p (write-char #\- stream))
    
    2495
    -                   (at-sign-p     (write-char #\+ stream)))
    
    2496
    -             (reshape-fixed stream mantissa exponent)))
    
    2560
    +             (cond (is-negative-p
    
    2561
    +		    (write-char #\- stream))
    
    2562
    +                   (at-sign-p
    
    2563
    +		    (write-char #\+ stream)))
    
    2564
    +             (scale-mantissa stream mantissa (1+ exponent) nil)))
    
    2497 2565
           (declare (dynamic-extent #'write-field))
    
    2498 2566
           (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    2499 2567
     	 
    

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