| ... |
... |
@@ -2140,6 +2140,7 @@ radix-R. If you have a power-list then pass it in as PL." |
|
2140
|
2140
|
;; +2 for the exponent marker and sign
|
|
2141
|
2141
|
(+ sign-len mantissa-len exp-digits 2)))
|
|
2142
|
2142
|
|
|
|
2143
|
+#+nil
|
|
2143
|
2144
|
(defun reshape-format-e (mantissa-text k drop-leading-zero-p)
|
|
2144
|
2145
|
"Reshape MANTISSA-TEXT of the form 'd[.dddd]Eee' from d2s or d2exp into
|
|
2145
|
2146
|
the displayed mantissa for ~E with scale factor K. If
|
| ... |
... |
@@ -2210,6 +2211,78 @@ radix-R. If you have a power-list then pass it in as PL." |
|
2210
|
2211
|
;; Finish with ".0".
|
|
2211
|
2212
|
(write-string ".0" s))))))
|
|
2212
|
2213
|
|
|
|
2214
|
+(defun scale-mantissa (stream mantissa-text k drop-leading-zero-p)
|
|
|
2215
|
+ "Write MANTISSA-TEXT to STREAM, shifting the decimal point so that
|
|
|
2216
|
+ the new dot lands K digits in from the start of the digit string.
|
|
|
2217
|
+ MANTISSA-TEXT is 'D' or 'D.DDDD' from d2s/d2exp.
|
|
|
2218
|
+ DROP-LEADING-ZERO-P controls whether the leading '0' before the dot
|
|
|
2219
|
+ is emitted when the result starts with '0.'. K=0 puts the dot
|
|
|
2220
|
+ before all digits; K=1 leaves it at the original position."
|
|
|
2221
|
+ (declare (type simple-string mantissa-text)
|
|
|
2222
|
+ (fixnum k))
|
|
|
2223
|
+ ;; Fast path: k=1, mantissa already in target form.
|
|
|
2224
|
+ (when (= k 1)
|
|
|
2225
|
+ (write-string mantissa-text stream)
|
|
|
2226
|
+ (unless (find #\. mantissa-text)
|
|
|
2227
|
+ (write-string ".0" stream))
|
|
|
2228
|
+ (return-from scale-mantissa))
|
|
|
2229
|
+ (let* ((has-dot (find #\. mantissa-text))
|
|
|
2230
|
+ (lead-char (char mantissa-text 0))
|
|
|
2231
|
+ ;; Where the stuff after the dot starts
|
|
|
2232
|
+ (tail-start (if has-dot 2 1))
|
|
|
2233
|
+ (tail-len (- (length mantissa-text) tail-start))
|
|
|
2234
|
+ (digit-count (1+ tail-len)))
|
|
|
2235
|
+ ;; Several cases to consider:
|
|
|
2236
|
+ ;;
|
|
|
2237
|
+ ;; * k is negative so the new dot preceeds the mantissa. Pad with
|
|
|
2238
|
+ ;; zeroes.
|
|
|
2239
|
+ ;; * k is so large that the dot is past the rightmost part of the
|
|
|
2240
|
+ ;; mantissa. Append enough zeroes and then add ".0"
|
|
|
2241
|
+ ;; * k is somewhere in the mantissa. Handling of this case
|
|
|
2242
|
+ ;; depends on if the new dot is to the left or to the right of
|
|
|
2243
|
+ ;; the original dot.
|
|
|
2244
|
+ (cond
|
|
|
2245
|
+ ;; Case 2: new dot at or before position 0.
|
|
|
2246
|
+ ((<= k 0)
|
|
|
2247
|
+ ;; Write "0." or "."
|
|
|
2248
|
+ (unless drop-leading-zero-p
|
|
|
2249
|
+ (write-char #\0 stream))
|
|
|
2250
|
+ (write-char #\. stream)
|
|
|
2251
|
+ ;; Insert zeros after the decimal but before the mantissa.
|
|
|
2252
|
+ (loop repeat (- k)
|
|
|
2253
|
+ do (write-char #\0 stream))
|
|
|
2254
|
+ ;; Add the mantissa, skipping any existing dot.
|
|
|
2255
|
+ (write-char lead-char stream)
|
|
|
2256
|
+ (when (plusp tail-len)
|
|
|
2257
|
+ (write-string mantissa-text stream :start tail-start)))
|
|
|
2258
|
+ ;; Case 1b: 1 < k < digit-count.
|
|
|
2259
|
+ ((< k digit-count)
|
|
|
2260
|
+ ;; Output the original mantissa up to the original dot.
|
|
|
2261
|
+ (write-char lead-char stream)
|
|
|
2262
|
+ (write-string mantissa-text stream
|
|
|
2263
|
+ :start tail-start
|
|
|
2264
|
+ :end (+ tail-start k -1))
|
|
|
2265
|
+ ;; Output the dot at the new position.
|
|
|
2266
|
+ (write-char #\. stream)
|
|
|
2267
|
+ ;; Output everything after the original dot.
|
|
|
2268
|
+ (write-string mantissa-text stream :start (+ tail-start k -1)))
|
|
|
2269
|
+ ;; Case 3: k >= digit-count.
|
|
|
2270
|
+ (t
|
|
|
2271
|
+ ;; Output the original mantissa, then everything after the
|
|
|
2272
|
+ ;; dot (if there was one).
|
|
|
2273
|
+ (write-char lead-char stream)
|
|
|
2274
|
+ (when (plusp tail-len)
|
|
|
2275
|
+ (write-string mantissa-text stream :start tail-start))
|
|
|
2276
|
+ ;; Pad with 0's
|
|
|
2277
|
+ (loop repeat (- k digit-count)
|
|
|
2278
|
+ do (write-char #\0 stream))
|
|
|
2279
|
+ ;; Finish with ".0"
|
|
|
2280
|
+ (write-string ".0" stream)))))
|
|
|
2281
|
+
|
|
|
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
|
+
|
|
2213
|
2286
|
(defun d2exp-precision (d k)
|
|
2214
|
2287
|
;; Compute precision for d2exp when CL requests D digits and the
|
|
2215
|
2288
|
;; scale factor is K."
|
| ... |
... |
@@ -2446,6 +2519,7 @@ radix-R. If you have a power-list then pass it in as PL." |
|
2446
|
2519
|
(fixnum exponent))
|
|
2447
|
2520
|
(reshape-format-e mantissa-text (1+ exponent) nil))
|
|
2448
|
2521
|
|
|
|
2522
|
+#+nil
|
|
2449
|
2523
|
(defun reshape-fixed (stream mantissa-text exponent)
|
|
2450
|
2524
|
"Adjust MANTISSA-TEXT is scaled exactly by 10^{EXPONENT} by moving the
|
|
2451
|
2525
|
decimal point. MANTISSA-TEXT is of the form 'd[.dddd]' from d2exp
|
| ... |
... |
@@ -2511,6 +2585,12 @@ radix-R. If you have a power-list then pass it in as PL." |
|
2511
|
2585
|
do (write-char #\0 stream))
|
|
2512
|
2586
|
;; Finish with ".0".
|
|
2513
|
2587
|
(write-string ".0" stream))))))
|
|
|
2588
|
+
|
|
|
2589
|
+(defun reshape-fixed (stream mantissa-text exponent)
|
|
|
2590
|
+ "Adjust MANTISSA-TEXT is scaled exactly by 10^{EXPONENT} by moving the
|
|
|
2591
|
+ decimal point. MANTISSA-TEXT is of the form 'd[.dddd]' from d2exp
|
|
|
2592
|
+ or d2s. The scaled value is written to STREAM."
|
|
|
2593
|
+ (scale-mantissa stream mantissa-text (1+ exponent) nil))
|
|
2514
|
2594
|
|
|
2515
|
2595
|
|
|
2516
|
2596
|
#+nil
|