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

How can I take this number: $100000.00 and make it $100,000.00, basically just taking any number and putting commas in the proper places... so if it was $100000000.00 it would automatically make it $100,000,000.00 and so forth?

Thank you.

Replies are listed 'Best First'.
Re: formatting numbers
by GrandFather (Saint) on Nov 08, 2007 at 03:04 UTC

    A simplistic version is:

    use warnings; use strict; for (qw($100000000.00 $100.00 $1000.00)) { my $value = reverse $_; $value =~ s/(\d{3})(?=\d)/$1,/g; $value = reverse $value; print "$_ => $value\n"; }

    Prints:

    $100000000.00 => $100,000,000.00 $100.00 => $100.00 $1000.00 => $1,000.00

    However that (as you can see) doesn't obey the convention that $1000.00 does not get a comma.


    Perl is environmentally friendly - it saves trees
      Is there a way to do this with sprintf, since I already format the number with it, like this:

      my $_accountBalance = $_db->{acct_bal}; print qq~Current Account Balance: ~ . sprintf('$%.2f', $_accountBalanc +e) . qq~! As of $_date~;


      When I used that code to format the number without the sprintf, it put the commas in the correct position, but after I got the correct format then used my sprintf it truncated everything down to 3 digits and the .xx

      Thanks again.

        Do the formatting in a sub:

        use warnings; use strict; print "Current Account Balance: ", asDollars ($_), "\n" for 100000000, 100, 1000; sub asDollars { my $value = reverse sprintf '$%.2f', shift; $value =~ s/(\d{3})(?=\d)/$1,/g; return scalar reverse $value; }

        Prints:

        Current Account Balance: $100,000,000.00 Current Account Balance: $100.00 Current Account Balance: $1,000.00

        Note that scalar is required in the return statement because reverse may otherwise see a list context.


        Perl is environmentally friendly - it saves trees
Re: formatting numbers
by kyle (Abbot) on Nov 08, 2007 at 03:32 UTC

    Looks like Number::Format would be an easy way to go. I haven't used it myself, but by my reading of the documentation, it would be as simple as:

    use Number::Format ':subs'; for (qw($100000000.00 $100.00 $1000.00)) { s/^\$//; $_ = '$' . format_number( $_, 2, 2 ); print; }

    It's even easier if there weren't the dollar sign at the front.

Re: formatting numbers
by ambrus (Abbot) on Nov 08, 2007 at 09:18 UTC

    See "How can I output my numbers with commas added?" in perlfaq5.

Re: formatting numbers
by TOD (Friar) on Nov 08, 2007 at 03:02 UTC
    sub number_format { my $num = shift; return $num unless $num; return undef unless $num =~ /^[0-9\.+-]+$/; $num =~ s/^([\+-])?//; my $sign = $1; $num =~ s/\.([0-9]+)$//; # must come before the call to abs(), be +cause here my $dec = $1; # a floating point value is still regard +ed as a string by perl, even if it's 0.00. $num = abs $num; $num = reverse $num; $num =~ s/(\d{3})/$1\,/g; $num =~ s/\.$//; $num = reverse $num; $num .= ".$dec" if $dec; $num = "$sign$num" if $sign; $num; }
    --------------------------------
    masses are the opiate for religion.
Re: formatting numbers
by aquarium (Curate) on Nov 08, 2007 at 03:36 UTC
    have a look here
    the hardest line to type correctly is: stty erase ^H
Re: formatting numbers
by johngg (Canon) on Nov 08, 2007 at 10:34 UTC
    You will find a variety of solutions in this thread.

    Cheers,

    JohnGG

Re: formatting numbers
by powerhouse (Friar) on Nov 08, 2007 at 06:53 UTC
    Here you go...
    #!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); use CGI qw(:standard); my %_numbers = ( 1 => "2020283.40", 2 => "02384829.94", 3 => "1038.92", 4 => "303.02", ); print header(); foreach my $num (sort {$a <=> $b} keys %_numbers) { my $_number = format_number(sprintf('$%.2f', $_numbers{$num})); print qq~$num) $_number~, br(); } sub format_number { my $num = shift; $_ = reverse $num; s/(\d{3})(?=\d)(?!\d*\.)/$1,/g; return (reverse $_); }
    That yeilds the following output:
    1) $2,020,283.40
    2) $2,384,829.94
    3) $1,038.92
    4) $303.02

    HTH,
    Richard
Re: formatting numbers
by apl (Monsignor) on Nov 08, 2007 at 12:36 UTC
    My favorite solution is:
    sub commify { my $text = reverse $_[0]; $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; return scalar reverse $text; }
    I regret wasting the node; i see Grandfather beat me to this solution...