summaryrefslogtreecommitdiff
path: root/module
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-02-13 21:30:51 +0100
committerAndy Wingo <wingo@pobox.com>2017-03-01 21:16:49 +0100
commitde5cf50aba1b9fd43c1fbd653c5cd9b7b973d52b (patch)
tree2b40ea5310b2ae9c4b8c288902b5ffd40cfbb6bc /module
parent4c7d1a64fa970c42f233af84dda49180a9836321 (diff)
i18n: 'number->locale-string' guesses the minimum number of decimals.
This feature was removed by 4aead68cdb86ca60cc372f0cd558cadda90ddec5. * module/ice-9/i18n.scm (number-decimal-string): Rewrite the case where DIGIT-COUNT is not an integer. (number->locale-string): Always pass FRACTION-DIGITS to 'number-decimal-string'. * test-suite/tests/format.test ("~h localized number")["1234.5"] ["padding", "padchar"]: Remove decimal specifier. * test-suite/tests/i18n.test ("number->locale-string") ["fraction", * test-suite/tests/i18n.test ("format ~h")["12 345,678"]: Remove decimal specifier. Remove one decimal. * doc/ref/api-i18n.texi (Number Input and Output): Update 'number->locale-string' doc to mention the number of decimals.
Diffstat (limited to 'module')
-rw-r--r--module/ice-9/i18n.scm40
1 files changed, 27 insertions, 13 deletions
diff --git a/module/ice-9/i18n.scm b/module/ice-9/i18n.scm
index 2363ba350..969c0589b 100644
--- a/module/ice-9/i18n.scm
+++ b/module/ice-9/i18n.scm
@@ -262,19 +262,35 @@
digits))))))
(define (number-decimal-string number digit-count)
- "Return a string representing the decimal part of NUMBER, with exactly
-DIGIT-COUNT digits"
- (if (integer? number)
- (make-string digit-count #\0)
-
- ;; XXX: This is brute-force and could be improved by following one
- ;; of the "Printing Floating-Point Numbers Quickly and Accurately"
- ;; papers.
+ "Return a string representing the decimal part of NUMBER. When
+DIGIT-COUNT is an integer, return exactly DIGIT-COUNT digits; when
+DIGIT-COUNT is #t, return as many decimals as necessary, up to an
+arbitrary limit."
+ (define max-decimals
+ 5)
+
+ ;; XXX: This is brute-force and could be improved by following one of
+ ;; the "Printing Floating-Point Numbers Quickly and Accurately"
+ ;; papers.
+ (if (integer? digit-count)
(let ((number (* (expt 10 digit-count)
(- number (floor number)))))
(string-pad (integer->string (round (inexact->exact number)))
digit-count
- #\0))))
+ #\0))
+ (let loop ((decimals 0))
+ (let ((number' (* number (expt 10 decimals))))
+ (if (or (= number' (floor number'))
+ (>= decimals max-decimals))
+ (let* ((fraction (- number'
+ (* (floor number)
+ (expt 10 decimals))))
+ (str (integer->string
+ (round (inexact->exact fraction)))))
+ (if (zero? fraction)
+ ""
+ str))
+ (loop (+ decimals 1)))))))
(define (%number-integer-part int grouping separator)
;; Process INT (a string denoting a number's integer part) and return a new
@@ -399,6 +415,7 @@ locale is used."
(locale %global-locale))
"Convert @var{number} (an inexact) into a string according to the cultural
conventions of either @var{locale} (a locale object) or the current locale.
+By default, print as many fractional digits as necessary, up to an upper bound.
Optionally, @var{fraction-digits} may be bound to an integer specifying the
number of fractional digits to be displayed."
@@ -421,10 +438,7 @@ number of fractional digits to be displayed."
(floor (abs number)))))
(dec (decimal-part
(number-decimal-string (abs number)
- (if (integer?
- fraction-digits)
- fraction-digits
- 0))))
+ fraction-digits)))
(grouping (locale-digit-grouping locale))
(separator (locale-thousands-separator locale)))