tphyahoo has asked for the wisdom of the Perl Monks concerning the following question:

Brother monks, I'm in europe, and here we use "," as a decimal separator. Is there any "locale savvy" way to treat comma formatted decimals as numbers in perl than s/,/./ and then back again after the calculation?

I tracked down perl currency formatting which seems to be sort of relevant but... ach, it all sounds so complicated. Isn't there some way to do this in a nice polite line of code?

As currently written, the following code is a "not numeric in multiplication" error. Cleanest fix?

use strict; use warnings; while (<DATA>) { print $_ * 2; } __DATA__ 1,1 2,2 3,3

Replies are listed 'Best First'.
Re: locale savvy comma as decimal operator
by japhy (Canon) on May 25, 2005 at 19:50 UTC
    I'd suggest looking at perllocale's "Locale Categories" section.

    The primary thing to realize is that you can't write numbers as 1.234.567,89 in your program, because you can't change Perl's interpretation of your code. However, if you have data in the form of 1.234.567,89, you can -- as the documentation shows -- use it without error.


    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      I could imagine a fairly simple overload module to make all this work, and work transparently. It'd make runtime slower but if its really desired, its certainly possible.
        Except that commas and periods are used elsewhere in Perl. You'd have to enforce the user employ specific whitespace:
        @array = (1,2,3,4); # would be a syntax error, no? @array = (1, 2, 3, 4); # would be ok
        You'd have to be very careful about the whole thing. I wouldn't even expect Perl 6 to have an easy I18N option about this (but I could be wrong, those Perl 6ers are tough bastards).

        Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
        How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: locale savvy comma as decimal operator
by holli (Abbot) on May 25, 2005 at 19:38 UTC
    You may want to have a look at my module Number::Format::Calc.
    use Number::Format::Calc ( -thousands_sep=>"", -decimal_point=>","); use strict; use warnings; while (<DATA>) { my $n = new Number::Format::Calc ($_); print $n * 2, "\n"; } __DATA__ 1,1 2,2 3,3
    Output:
    2,2 4,4 6,6


    holli, /regexed monk/
      This sounds good. I'm going to give it a try.
Re: locale savvy comma as decimal operator
by sh1tn (Priest) on May 25, 2005 at 22:08 UTC
    use strict; use warnings; while (<DATA>) { s/(\.(\d+))(?=.*,)/$2/g; s/(\d+),?(\d*)/print((($1.'.'.$2)*2),"\n")/eg; } __DATA__ 1,2 1.23,456 1.23.456,789 STDOUT: 2.4 246.912 246913.578


Re: locale savvy comma as decimal operator
by TedPride (Priest) on May 25, 2005 at 21:43 UTC
    The following works fine. You probably tried something like this yourself, but without the test for an empty field.
    use strict; use warnings; while (<DATA>) { chomp; s/,/\./; $_ *= 2 if $_; s/\./,/; print "$_\n"; } __DATA__ 1, 2,22 3,345
    EDIT: I may have misread your post. If you were looking for a neat line of code to replace the above, I'm afraid there probably isn't one.

    EDIT:
    japhy: Your link looks promising for providing the simplest solution, but doesn't really explain how. A short piece of code might be nice for us stupid people.

    sh1tn: I may be missing something here, but don't numbers usually have only one decimal point?