Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Numbers with commas

by Anonymous Monk
on May 13, 2004 at 01:11 UTC ( [id://352950]=perlquestion: print w/replies, xml ) Need Help??

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

#!/usr/bin/perl use warnings; use strict; my $num = "1,002,345"; my $total = $num + 1000;
Perl doesn't see commas as being part of a number?
perl test.pl Argument "1,002,345" isn't numeric in addition (+) at test.pl line 8.

Replies are listed 'Best First'.
Re: Numbers with commas
by tachyon (Chancellor) on May 13, 2004 at 01:25 UTC

    Perl doesn't see commas as being part of a number?

    Given that it is a string that is less than suprising. In fact Perl tries its best to make a number out of the string - in fact it does find the number 1 (the bit before the first comma).....

    C:\>perl -e "print '1,000,000' + 1000" 1001 C:\>

    What you see is a warning as Perl knows that effectively doing an atoi()ish thing on a string may give unexpected results. Just remove the commas first and re-add them for output.

    sub decommify { my ( $number ) = @_; $number =~ tr/,//d; return $number } sub commify { my ( $number ) = @_; return undef unless $number; ( $number, my $dec ) = $number =~ m!([+-]?\d+)\.?(\d*)!; return undef unless $number; $number =~ s/(\d)(?=(\d{3})+(\D|$))/$1,/g if length($number) > 3; return $dec ? "$number.$dec" : $number; } print commify( decommify("1,000,001.123456789") + 1000 ); __DATA__ 1,001,001.12345679

    cheers

    tachyon

      From perlfaq5:
      How can I output my numbers with commas added? This one will do it for you: sub commify { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; }

        There are a range of variations on the commify theme. That faq version is probably the worst. It is inefficient as it backtracks to do the job and also chokes on things like $1000 or 'string 123456'. The regex in my sub is one of merlyns creations but it chokes on >3 numbers after the decimal point without handling them separately. The Perl cookbook version:

        sub commify { my $text = reverse $_[0]; $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; return scalar reverse $text; }

        Is more more fault tolerant than the one from the faq.

        cheers

        tachyon

Re: Numbers with commas
by TilRMan (Friar) on May 13, 2004 at 01:42 UTC

    If you are merely using commas for readability, you can use underscores instead. But you can only use them in unquoted numbers, not strings.

    print 1_000_000 + 1000; # 1001000 print '1_000_000' + 1000; # Warning!

    BTW, Perl will completely ignore the underscores, so if you accidentally mistype 1_000_00_000, you'll get 100 million instead of 1 billion -- and no warning.

Re: Numbers with commas
by Gunth (Scribe) on May 13, 2004 at 01:47 UTC
    tachyon gave a good soltution. Good for if you're getting the data from someplace else. If it's just for your own sake of readibility you can use underscores (_) instead of commas.
    #!/usr/bin/perl use warnings; use strict; my $num = 1_002_345; my $total = $num + 1000;
    And tachyon commify will work, but the one provided in the Perl Cookbook 2.17 is more efficent.
    sub commify { my $text = reverse $_[0]; $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; return scalar reverse $text; }
    -Will
Re: Numbers with commas
by l3nz (Friar) on May 13, 2004 at 07:32 UTC
    As far as I know, Perl only allows underscores as number beautyfiers, like 1_000_230 instead of 1,000,230, but I guess they get thrown out by the parser as soon as they're found.

    The point with parsing a (maybe user input) string is that there is no correct way to handle commas and dots if yuou don't take you LOCALE into consideration. The string 2,500 written by an american is two thousand five hundred, by an italian is two and a half. And such numbers can be rather ambiguous, both in reading and in input. The standard computer notation uses only the dot for the decimal part and no commas and it's in most cases unambiguous. In all other cases you'll have to rely on the locale, and you should not expect a language to do it by itself (Java does if you don't tell it; but then, how do you know which version of the system was installed on the Linux box of your Hungarian branch?)

Re: Numbers with commas
by sulfericacid (Deacon) on May 13, 2004 at 01:15 UTC
    That's definitely a new one to me, never bumped into this problem but I would have assumed commas would be ignored when doing mathematical equations.

    You could always s/,// for $num though.

    $num =~ s/,//;


    "Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

    sulfericacid

      <pedant>
        $num =~ s/,//g;
      </pedant>

      Sorry...

Re: Numbers with commas
by benrwebb (Scribe) on May 13, 2004 at 04:31 UTC
    Um, no. I'm not sure if any language I can think of off hand that recognizes a string of commas and digits as a number, but then I don't write as much code as I once did, pretty much all of my recent work is perl.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://352950]
Approved by pbeckingham
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2024-03-28 19:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found