[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 01/04: i18n: 'number->locale-string' guesses the minimum
From: |
Ludovic Courtès |
Subject: |
[Guile-commits] 01/04: i18n: 'number->locale-string' guesses the minimum number of decimals. |
Date: |
Mon, 13 Feb 2017 16:12:08 -0500 (EST) |
civodul pushed a commit to branch stable-2.0
in repository guile.
commit 4b2b867c21fcf1cd751c4809edc8dc0f691daf32
Author: Ludovic Courtès <address@hidden>
Date: Mon Feb 13 21:30:51 2017 +0100
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.
---
doc/ref/api-i18n.texi | 10 ++++++----
module/ice-9/i18n.scm | 40 +++++++++++++++++++++++++++-------------
test-suite/tests/format.test | 6 +++---
test-suite/tests/i18n.test | 16 ++++++++--------
4 files changed, 44 insertions(+), 28 deletions(-)
diff --git a/doc/ref/api-i18n.texi b/doc/ref/api-i18n.texi
index fa3fe99..0a27285 100644
--- a/doc/ref/api-i18n.texi
+++ b/doc/ref/api-i18n.texi
@@ -1,7 +1,7 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
address@hidden Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006,
2007, 2009, 2010
address@hidden Free Software Foundation, Inc.
address@hidden Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006,
2007,
address@hidden 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]
diff --git a/module/ice-9/i18n.scm b/module/ice-9/i18n.scm
index 2363ba3..969c058 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)))
diff --git a/test-suite/tests/format.test b/test-suite/tests/format.test
index 9acbbcc..5f43367 100644
--- a/test-suite/tests/format.test
+++ b/test-suite/tests/format.test
@@ -124,13 +124,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)
diff --git a/test-suite/tests/i18n.test b/test-suite/tests/i18n.test
index db7fa65..0475c3b 100644
--- a/test-suite/tests/i18n.test
+++ b/test-suite/tests/i18n.test
@@ -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"