1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 03:30:27 +02:00

i18n: 'number->locale-string' guesses the minimum number of decimals.

This feature was removed by 4aead68cdb.

* 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.
This commit is contained in:
Ludovic Courtès 2017-02-13 21:30:51 +01:00 committed by Andy Wingo
parent 4c7d1a64fa
commit de5cf50aba
4 changed files with 43 additions and 27 deletions

View file

@ -1,7 +1,7 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2009, 2010
@c Free Software Foundation, Inc.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
@c 2009, 2010, 2017 Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node Internationalization
@ -263,8 +263,10 @@ Reference Manual}).
@deffn {Scheme Procedure} number->locale-string number [fraction-digits [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. Optionally, @var{fraction-digits} may be bound to an
integer specifying the number of fractional digits to be displayed.
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.
@end deffn
@deffn {Scheme Procedure} monetary-amount->locale-string amount intl? [locale]

View file

@ -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)
"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.
;; 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)))

View file

@ -133,13 +133,13 @@
(with-test-prefix "~h localized number"
(pass-if "1234.5"
(string=? (format #f "~,1h" 1234.5) "1234.5"))
(string=? (format #f "~h" 1234.5) "1234.5"))
(pass-if "padding"
(string=? (format #f "~6h" 123.2) " 123"))
(string=? (format #f "~6h" 123.2) " 123.2"))
(pass-if "padchar"
(string=? (format #f "~8,1,'*h" 123.2) "***123.2"))
(string=? (format #f "~8,,'*h" 123.2) "***123.2"))
(pass-if "decimals"
(string=? (format #f "~,2h" 123.4567)

View file

@ -506,7 +506,7 @@
(pass-if-equal "fraction"
"1234.567"
(number->locale-string 1234.567 3))
(number->locale-string 1234.567))
(pass-if-equal "fraction, 1 digit"
"1234.6"
@ -545,7 +545,7 @@
(under-french-locale-or-unresolved
(lambda ()
(let ((fr (make-locale LC_ALL %french-locale-name)))
(number->locale-string 1234.567 3 fr)))))
(number->locale-string 1234.567 #t fr)))))
(pass-if-equal "fraction, 1 digit"
"1 234,6"
@ -562,23 +562,23 @@
(with-test-prefix "French"
(pass-if-equal "12345.6789"
"12 345,6789"
(pass-if-equal "12345.678"
"12 345,678"
(under-french-locale-or-unresolved
(lambda ()
(if (null? (locale-digit-grouping %french-locale))
(throw 'unresolved)
(format #f "~,4:h" 12345.6789 %french-locale))))))
(format #f "~:h" 12345.678 %french-locale))))))
(with-test-prefix "English"
(pass-if-equal "12345.6789"
"12,345.6789"
(pass-if-equal "12345.678"
"12,345.678"
(under-american-english-locale-or-unresolved
(lambda ()
(if (null? (locale-digit-grouping %american-english-locale))
(throw 'unresolved)
(format #f "~,4:h" 12345.6789
(format #f "~:h" 12345.678
%american-english-locale)))))))
(with-test-prefix "monetary-amount->locale-string"