diff options
author | Ludovic Courtès <ludo@gnu.org> | 2017-02-13 21:30:51 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-03-01 21:16:49 +0100 |
commit | de5cf50aba1b9fd43c1fbd653c5cd9b7b973d52b (patch) | |
tree | 2b40ea5310b2ae9c4b8c288902b5ffd40cfbb6bc /module | |
parent | 4c7d1a64fa970c42f233af84dda49180a9836321 (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.scm | 40 |
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))) |