| ... |
... |
@@ -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
|
|