* Formatted output with locale @ 2016-11-13 16:56 dev [not found] ` <CAMvDHVA+TcZg-ak_Nt6vGQW5w4B4KSmEPd3uEziJ0EDXbPp54A@mail.gmail.com> 2016-11-17 11:02 ` Ludovic Courtès 0 siblings, 2 replies; 7+ messages in thread From: dev @ 2016-11-13 16:56 UTC (permalink / raw) To: guile-user Hi there, I have problems to get a proper formatting using the (ice-9 format) module. In my code, I need to deal with monetary figures, but I fail to get the correct format for my German locale. Let's say I have one hundred thousand Euros. The correct format to output this in de_DE.utf-8 would be 100.000,00 EUR (with 2 decimals) Now I tried: (setlocale LC_ALL "de_DE.UTF-8") (use-modules (ice-9 format)) (define a 100000.00) (format #t "~12,2h EUR~%" a) (format #t "~,,12$ EUR~%" a) (format #t "~12,2f EUR~%" a) But this is what Guile gives to me: 100.000,0 EUR 100000.00 EUR 100000.00 EUR None is correct. What did I miss? -Martin ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <CAMvDHVA+TcZg-ak_Nt6vGQW5w4B4KSmEPd3uEziJ0EDXbPp54A@mail.gmail.com>]
* Fwd: Formatted output with locale [not found] ` <CAMvDHVA+TcZg-ak_Nt6vGQW5w4B4KSmEPd3uEziJ0EDXbPp54A@mail.gmail.com> @ 2016-11-14 6:06 ` Vladimir Zhbanov 0 siblings, 0 replies; 7+ messages in thread From: Vladimir Zhbanov @ 2016-11-14 6:06 UTC (permalink / raw) To: guile-user Martin, I'm sorry for the private reply, my fault :-( Forward to the list. ---------- Forwarded message ---------- From: Vladimir Zhbanov <vzhbanov@gmail.com> Date: Mon, 14 Nov 2016 09:03:19 +0300 Subject: Re: Formatted output with locale To: dev@famic.de Hi Martin, On 11/13/16, dev@famic.de <dev@famic.de> wrote: > Hi there, > I have problems to get a proper formatting using the (ice-9 format) > module. In my code, I need to deal with monetary figures, but I fail > to get the correct format for my German locale. > Let's say I have one hundred thousand Euros. The correct format to output > this in de_DE.utf-8 would be > 100.000,00 EUR > (with 2 decimals) > > Now I tried: > (setlocale LC_ALL "de_DE.UTF-8") > (use-modules (ice-9 format)) > (define a 100000.00) > (format #t "~12,2h EUR~%" a) > (format #t "~,,12$ EUR~%" a) > (format #t "~12,2f EUR~%" a) > > But this is what Guile gives to me: > 100.000,0 EUR > 100000.00 EUR > 100000.00 EUR > > None is correct. What did I miss? > -Martin Looking at the `format' code for option `h' I see the procedure `number->locale-string' is used. OK, let's do some experiments: scheme@(guile-user)> (setlocale LC_ALL) $2 = "ru_RU.UTF-8" scheme@(guile-user)> ,use (ice-9 i18n) scheme@(guile-user)> (number->locale-string 10.0 5) $3 = "10,0" scheme@(guile-user)> (number->locale-string .00003 2) $4 = "3,0e" scheme@(guile-user)> (number->locale-string .00003 1) $5 = "3,0" scheme@(guile-user)> (number->locale-string .00003 3) $6 = "3,0e-" scheme@(guile-user)> (number->locale-string .0 3) $7 = "-0,0" scheme@(guile-user)> (number->locale-string .0 10) $8 = "-0,0" scheme@(guile-user)> (number->locale-string .0 1) $9 = "-0,0" Now for the procedure monetary-amount->locale-string: scheme@(guile-user)> (monetary-amount->locale-string .0 #t) $10 = "-0.0 RUB " scheme@(guile-user)> (monetary-amount->locale-string 100000.0 #t) $11 = "100\xa0000.0 RUB " scheme@(guile-user)> (monetary-amount->locale-string .00003 #t) $12 = "3.0e RUB " And my guile version: scheme@(guile-user)> (version) $13 = "2.0.11" It seems `number->locale-string' is broken. If I do, e.g. (number->locale-string .00003 10) it yields "3,0e-5" If the last arg decreases, it just trims the number of characters after comma, which is wrong in this case. Output for zero is funny, too. Regards, Vladimir ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Formatted output with locale 2016-11-13 16:56 Formatted output with locale dev [not found] ` <CAMvDHVA+TcZg-ak_Nt6vGQW5w4B4KSmEPd3uEziJ0EDXbPp54A@mail.gmail.com> @ 2016-11-17 11:02 ` Ludovic Courtès 2016-11-17 16:07 ` Eli Zaretskii 2016-11-17 16:53 ` Vladimir Zhbanov 1 sibling, 2 replies; 7+ messages in thread From: Ludovic Courtès @ 2016-11-17 11:02 UTC (permalink / raw) To: guile-user Hi! dev@famic.de skribis: > I have problems to get a proper formatting using the (ice-9 format) > module. In my code, I need to deal with monetary figures, but I fail > to get the correct format for my German locale. > Let's say I have one hundred thousand Euros. The correct format to output > this in de_DE.utf-8 would be > 100.000,00 EUR > (with 2 decimals) > > Now I tried: > (setlocale LC_ALL "de_DE.UTF-8") > (use-modules (ice-9 format)) > (define a 100000.00) > (format #t "~12,2h EUR~%" a) > (format #t "~,,12$ EUR~%" a) > (format #t "~12,2f EUR~%" a) > > But this is what Guile gives to me: > 100.000,0 EUR > 100000.00 EUR > 100000.00 EUR It seems to work as advertised for me: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,use(ice-9 i18n) scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "fr_FR.utf8")) $13 = "10 000,01" scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "de_DE.utf8")) $14 = "10.000,01" scheme@(guile-user)> ,use(ice-9 format) scheme@(guile-user)> (setlocale LC_ALL "de_DE.utf8") $15 = "de_DE.utf8" scheme@(guile-user)> (format #f "~12,2h" 10000.01) $16 = " 10.000,01" --8<---------------cut here---------------end--------------->8--- That’s on GNU/Linux (glibc 2.24). Note that number formatting data comes from the C library. What C library do you use? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Formatted output with locale 2016-11-17 11:02 ` Ludovic Courtès @ 2016-11-17 16:07 ` Eli Zaretskii 2016-11-17 16:53 ` Vladimir Zhbanov 1 sibling, 0 replies; 7+ messages in thread From: Eli Zaretskii @ 2016-11-17 16:07 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guile-user > From: ludo@gnu.org (Ludovic Courtès) > Date: Thu, 17 Nov 2016 12:02:06 +0100 > > It seems to work as advertised for me: > > --8<---------------cut here---------------start------------->8--- > scheme@(guile-user)> ,use(ice-9 i18n) > scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "fr_FR.utf8")) > $13 = "10 000,01" > scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "de_DE.utf8")) > $14 = "10.000,01" > scheme@(guile-user)> ,use(ice-9 format) > scheme@(guile-user)> (setlocale LC_ALL "de_DE.utf8") > $15 = "de_DE.utf8" > scheme@(guile-user)> (format #f "~12,2h" 10000.01) > $16 = " 10.000,01" > --8<---------------cut here---------------end--------------->8--- > > That’s on GNU/Linux (glibc 2.24). It works for me as well, on MS-Windows (although I need to use a non-UTF-8 codeset in the locales). ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Formatted output with locale 2016-11-17 11:02 ` Ludovic Courtès 2016-11-17 16:07 ` Eli Zaretskii @ 2016-11-17 16:53 ` Vladimir Zhbanov 2016-11-21 9:31 ` Ludovic Courtès 1 sibling, 1 reply; 7+ messages in thread From: Vladimir Zhbanov @ 2016-11-17 16:53 UTC (permalink / raw) To: guile-user On Thu, Nov 17, 2016 at 12:02:06PM +0100, Ludovic Courtès wrote: > Hi! > > dev@famic.de skribis: > > > I have problems to get a proper formatting using the (ice-9 format) > > module. In my code, I need to deal with monetary figures, but I fail > > to get the correct format for my German locale. > > Let's say I have one hundred thousand Euros. The correct format to output > > this in de_DE.utf-8 would be > > 100.000,00 EUR > > (with 2 decimals) > > > > Now I tried: > > (setlocale LC_ALL "de_DE.UTF-8") > > (use-modules (ice-9 format)) > > (define a 100000.00) > > (format #t "~12,2h EUR~%" a) > > (format #t "~,,12$ EUR~%" a) > > (format #t "~12,2f EUR~%" a) > > > > But this is what Guile gives to me: > > 100.000,0 EUR > > 100000.00 EUR > > 100000.00 EUR > > It seems to work as advertised for me: > > --8<---------------cut here---------------start------------->8--- > scheme@(guile-user)> ,use(ice-9 i18n) > scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "fr_FR.utf8")) > $13 = "10 000,01" > scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "de_DE.utf8")) > $14 = "10.000,01" > scheme@(guile-user)> ,use(ice-9 format) > scheme@(guile-user)> (setlocale LC_ALL "de_DE.utf8") > $15 = "de_DE.utf8" > scheme@(guile-user)> (format #f "~12,2h" 10000.01) > $16 = " 10.000,01" > --8<---------------cut here---------------end--------------->8--- What does it output if you type (number->locale-string 10000.00 2 (make-locale LC_ALL "fr_FR.utf8")) that is with two zeros after the point? I would expect the same two zeros if the second argument is 2... Am I wrong? > That’s on GNU/Linux (glibc 2.24). > > Note that number formatting data comes from the C library. What C > library do you use? My glibc version is 2.19. Thanks -- Vladimir ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Formatted output with locale 2016-11-17 16:53 ` Vladimir Zhbanov @ 2016-11-21 9:31 ` Ludovic Courtès 2016-11-23 12:06 ` Vladimir Zhbanov 0 siblings, 1 reply; 7+ messages in thread From: Ludovic Courtès @ 2016-11-21 9:31 UTC (permalink / raw) To: guile-user Vladimir Zhbanov <vzhbanov@gmail.com> skribis: > On Thu, Nov 17, 2016 at 12:02:06PM +0100, Ludovic Courtès wrote: >> Hi! >> >> dev@famic.de skribis: >> >> > I have problems to get a proper formatting using the (ice-9 format) >> > module. In my code, I need to deal with monetary figures, but I fail >> > to get the correct format for my German locale. >> > Let's say I have one hundred thousand Euros. The correct format to output >> > this in de_DE.utf-8 would be >> > 100.000,00 EUR >> > (with 2 decimals) >> > >> > Now I tried: >> > (setlocale LC_ALL "de_DE.UTF-8") >> > (use-modules (ice-9 format)) >> > (define a 100000.00) >> > (format #t "~12,2h EUR~%" a) >> > (format #t "~,,12$ EUR~%" a) >> > (format #t "~12,2f EUR~%" a) >> > >> > But this is what Guile gives to me: >> > 100.000,0 EUR >> > 100000.00 EUR >> > 100000.00 EUR >> >> It seems to work as advertised for me: >> >> --8<---------------cut here---------------start------------->8--- >> scheme@(guile-user)> ,use(ice-9 i18n) >> scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "fr_FR.utf8")) >> $13 = "10 000,01" >> scheme@(guile-user)> (number->locale-string 10000.01 2 (make-locale LC_ALL "de_DE.utf8")) >> $14 = "10.000,01" >> scheme@(guile-user)> ,use(ice-9 format) >> scheme@(guile-user)> (setlocale LC_ALL "de_DE.utf8") >> $15 = "de_DE.utf8" >> scheme@(guile-user)> (format #f "~12,2h" 10000.01) >> $16 = " 10.000,01" >> --8<---------------cut here---------------end--------------->8--- > > What does it output if you type > (number->locale-string 10000.00 2 (make-locale LC_ALL "fr_FR.utf8")) > > that is with two zeros after the point? I get this: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (number->locale-string 10000.00 2 (make-locale LC_ALL "fr_FR.utf8")) $1 = "10 000,0" scheme@(guile-user)> (number->locale-string 10000.00 4 (make-locale LC_ALL "fr_FR.utf8")) $2 = "10 000,0" --8<---------------cut here---------------end--------------->8--- … and that’s definitely a bug. Could you send it to bug-guile@gnu.org so we keep track of it? >> That’s on GNU/Linux (glibc 2.24). >> >> Note that number formatting data comes from the C library. What C >> library do you use? > > My glibc version is 2.19. It might be responsible for the incorrect thousand and fraction separators you observe in the de_DE output. To dig further, you can check the low-level info provided by ‘nl_langinfo’: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,use(ice-9 i18n) scheme@(guile-user)> (define l (make-locale LC_ALL "de_DE.utf8")) scheme@(guile-user)> (locale-digit-grouping l) $2 = (3 3 . #-1#) scheme@(guile-user)> (locale-decimal-point l) $3 = "," scheme@(guile-user)> (locale-thousands-separator l) $4 = "." --8<---------------cut here---------------end--------------->8--- Thanks, Ludo’. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Formatted output with locale 2016-11-21 9:31 ` Ludovic Courtès @ 2016-11-23 12:06 ` Vladimir Zhbanov 0 siblings, 0 replies; 7+ messages in thread From: Vladimir Zhbanov @ 2016-11-23 12:06 UTC (permalink / raw) Cc: guile-user [-- Attachment #1: Type: text/plain, Size: 4928 bytes --] Hi Ludovic, ... >> What does it output if you type >> (number->locale-string 10000.00 2 (make-locale LC_ALL "fr_FR.utf8")) >> >> that is with two zeros after the point? > > I get this: > > --8<---------------cut here---------------start------------->8--- > scheme@(guile-user)> (number->locale-string 10000.00 2 (make-locale LC_ALL > "fr_FR.utf8")) > $1 = "10 000,0" > scheme@(guile-user)> (number->locale-string 10000.00 4 (make-locale LC_ALL > "fr_FR.utf8")) > $2 = "10 000,0" > --8<---------------cut here---------------end--------------->8--- > > … and that’s definitely a bug. > > Could you send it to bug-guile@gnu.org so we keep track of it? I don't know how to do this, sorry. I see bugs are numbered there. Is there a special form for bug submission? Or just will an email do? And how to answer the mail already being there if I'm not subscribed? > >>> That’s on GNU/Linux (glibc 2.24). >>> >>> Note that number formatting data comes from the C library. What C >>> library do you use? >> >> My glibc version is 2.19. > > It might be responsible for the incorrect thousand and fraction > separators you observe in the de_DE output. To dig further, you can > check the low-level info provided by ‘nl_langinfo’: > > --8<---------------cut here---------------start------------->8--- > scheme@(guile-user)> ,use(ice-9 i18n) > scheme@(guile-user)> (define l (make-locale LC_ALL "de_DE.utf8")) > scheme@(guile-user)> (locale-digit-grouping l) > $2 = (3 3 . #-1#) > scheme@(guile-user)> (locale-decimal-point l) > $3 = "," > scheme@(guile-user)> (locale-thousands-separator l) > $4 = "." > --8<---------------cut here---------------end--------------->8--- My Scheme output is as follows: --------------------------------8<-------------------------------- scheme@(guile-user)> ,use (ice-9 i18n) scheme@(guile-user)> (define l (make-locale LC_ALL "ru_RU.UTF-8")) scheme@(guile-user)> (locale-digit-grouping l) $2 = (3 3 . #-1#) scheme@(guile-user)> (locale-decimal-point l) $3 = "," scheme@(guile-user)> (locale-thousands-separator l) $4 = "\xa0" -------------------------------->8-------------------------------- (The last result is weird on my system though it's another story.) I don't think all this somehow affects my output. I seem to have found several bugs in number->locale-string(). 1) Superfluous minus sign in output of zero: --------------------------------8<-------------------------------- scheme@(guile-user)> (number->locale-string 0) $5 = "0" scheme@(guile-user)> (number->locale-string 0.0) $6 = "-0,0" -------------------------------->8-------------------------------- For this case a patch against the master branch is attached. 2) Wrong output for numbers less than 0.001 --------------------------------8<-------------------------------- scheme@(guile-user)> (number->locale-string 0.0009) $7 = "9,0e-4" scheme@(guile-user)> (number->locale-string 0.0009 2) $8 = "9,0e" scheme@(guile-user)> (number->locale-string 0.0009 1) $9 = "9,0" scheme@(guile-user)> (number->locale-string 0.0009 0) $10 = "9" -------------------------------->8-------------------------------- I don't really know how to proceed here. My naive approach is to not modify the decimal part in such cases. The solution is in the second patch. 3) Should output for the below cases differ? --------------------------------8<-------------------------------- scheme@(guile-user)> (number->locale-string 10 2) $2 = "10" scheme@(guile-user)> (number->locale-string 10.0 2) $3 = "10,0" -------------------------------->8-------------------------------- 4) Definitely a bug with different fraction-digits: --------------------------------8<-------------------------------- scheme@(guile-user)> (number->locale-string 10.0 2) $3 = "10,0" scheme@(guile-user)> (number->locale-string 10.0 4) $4 = "10,0" -------------------------------->8-------------------------------- I think, the decimal parts should be zero padded to get desired result. 5) Eventually, I don't really understand why substring() is used to cut decimals: --------------------------------8<-------------------------------- scheme@(guile-user)> (number->locale-string 0.99 0) $8 = "0" scheme@(guile-user)> (number->locale-string 0.99 1) $9 = "0,9" scheme@(guile-user)> (number->locale-string 0.99 2) $10 = "0,99" -------------------------------->8-------------------------------- I would prefer some rounding here in order to have the result as follows: --Desired results---------------8<-------------------------Begin-- scheme@(guile-user)> (number->locale-string 0.99 0) $8 = "1" scheme@(guile-user)> (number->locale-string 0.99 1) $9 = "1,0" scheme@(guile-user)> (number->locale-string 0.99 2) $10 = "0,99" --Desired results--------------->8---------------------------End-- Regards, Vladimir [-- Attachment #2: 0001-Fix-output-of-0.0-in-number-locale-string.patch --] [-- Type: application/octet-stream, Size: 936 bytes --] From 679acd3803b07e63a1d3a221d6b13eee969a745e Mon Sep 17 00:00:00 2001 From: Vladimir Zhbanov <vzhbanov@gmail.com> Date: Wed, 23 Nov 2016 12:56:09 +0300 Subject: [PATCH 1/2] Fix output of 0.0 in number->locale-string(). --- module/ice-9/i18n.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/ice-9/i18n.scm b/module/ice-9/i18n.scm index 1d12dd0..5e7e1cb 100644 --- a/module/ice-9/i18n.scm +++ b/module/ice-9/i18n.scm @@ -387,7 +387,7 @@ number of fractional digits to be displayed." (substring dec 0 fraction-digits) dec)))))) - (let* ((external-repr (number->string (if (> number 0) + (let* ((external-repr (number->string (if (>= number 0) number (- number)))) (int+dec (string-split external-repr #\.)) -- 2.1.4 [-- Attachment #3: 0002-Fix-number-locale-string-for-numbers-less-than-.001.patch --] [-- Type: application/octet-stream, Size: 2091 bytes --] From 3c2e718eff6ab1d8f529185896a4ea841122e0f0 Mon Sep 17 00:00:00 2001 From: Vladimir Zhbanov <vzhbanov@gmail.com> Date: Wed, 23 Nov 2016 14:26:55 +0300 Subject: [PATCH 2/2] Fix number->locale-string() for numbers less than .001. For such numbers, internally used number->string can return strings containing exponent, such as, say "9.0e-4". Just cutting of the decimal part in this case is wrong, so the solution presented here is just to use decimal part unchanged in such cases. --- module/ice-9/i18n.scm | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/module/ice-9/i18n.scm b/module/ice-9/i18n.scm index 5e7e1cb..0c4d9f6 100644 --- a/module/ice-9/i18n.scm +++ b/module/ice-9/i18n.scm @@ -378,14 +378,17 @@ number of fractional digits to be displayed." (else ""))) (decimal-part (lambda (dec) - (if (or (string=? dec "") (eq? 0 fraction-digits)) - "" - (string-append (locale-decimal-point locale) - (if (and (integer? fraction-digits) - (< fraction-digits - (string-length dec))) - (substring dec 0 fraction-digits) - dec)))))) + (if (string-index dec #\-) + ;; For strings like "1.0e-4" + (string-append (locale-decimal-point locale) dec) + (if (or (string=? dec "") (eq? 0 fraction-digits)) + "" + (string-append (locale-decimal-point locale) + (if (and (integer? fraction-digits) + (< fraction-digits + (string-length dec))) + (substring dec 0 fraction-digits) + dec))))))) (let* ((external-repr (number->string (if (>= number 0) number -- 2.1.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-11-23 12:06 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-11-13 16:56 Formatted output with locale dev [not found] ` <CAMvDHVA+TcZg-ak_Nt6vGQW5w4B4KSmEPd3uEziJ0EDXbPp54A@mail.gmail.com> 2016-11-14 6:06 ` Fwd: " Vladimir Zhbanov 2016-11-17 11:02 ` Ludovic Courtès 2016-11-17 16:07 ` Eli Zaretskii 2016-11-17 16:53 ` Vladimir Zhbanov 2016-11-21 9:31 ` Ludovic Courtès 2016-11-23 12:06 ` Vladimir Zhbanov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).