I've run some benchmarks against some of the solutions given and it turns out that the one I gave here using split/reverse/map/reverse performs like a dog. However, I found another way with substr that does much better. Here are the benchmarks

Rate Split Molt FAQ Cdarke PrefUN Substr Split 8.00/s -- -15% -31% -39% -53% -74% Molt 9.36/s 17% -- -19% -29% -45% -70% FAQ 11.5/s 44% 23% -- -12% -32% -63% Cdarke 13.2/s 64% 41% 14% -- -22% -58% PrefUN 16.9/s 111% 80% 47% 28% -- -46% Substr 31.3/s 291% 234% 171% 138% 85% --

and here is the benchmark code

use strict; use warnings; use Benchmark qw(cmpthese); my @numbers; push @numbers, int rand 1e9 for 1 .. 1000; my $rcUseCdarke = sub { my $res = useCdarke($_) for @numbers; }; my $rcUseFAQ = sub { my $res = useFAQ($_) for @numbers; }; my $rcUseMolt = sub { my $res = useMolt($_) for @numbers; }; my $rcUsePrefUN = sub { my $res = usePrefUN($_) for @numbers; }; my $rcUseJwkrahn = sub { my $res = useJwkrahn($_) for @numbers; }; my $rcUseSplit = sub { my $res = useSplit($_) for @numbers; }; my $rcUseSubstr = sub { my $res = useSubstr($_) for @numbers; }; cmpthese (50, { Cdarke => $rcUseCdarke, FAQ => $rcUseFAQ, Jwkrahn => $rcUseJwkrahn, Molt => $rcUseMolt, PrefUN => $rcUsePrefUN, Split => $rcUseSplit, Substr => $rcUseSubstr }); sub useCdarke { my $number = reverse shift; $number =~ s/(\d{3})/$1,/g; $number = reverse $number; return $number; } sub useFAQ { my $number = reverse shift; $number =~ s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g; return $number; } sub useJwkrahn { return scalar reverse join ',', unpack '(a3)*', reverse shift; } sub useMolt { my $number = shift; while ($number =~ s/(\d)(\d\d\d)(?!\d)/$1,$2/) {}; return $number; } sub usePrefUN { my $num = reverse shift; my @threes = $num =~ /(.{1,3})/g; return scalar reverse join ',', @threes; } sub useSplit { my $ct = 0; my $len = length $_[0]; return join q{}, reverse map { ++ $ct % 3 ? $_ : $ct == $len ? $_ : ($_, q{,}) } reverse split m{}, $_[0]; } sub useSubstr { my $number = shift; my $offset = -3; while (abs $offset < length $number) { substr $number, $offset , 0, q{,}; $offset -= 4; } return $number; }

I hope this is of interest.

Cheers,

JohnGG

Update: New benchmarks incorporating corrected split/reverse/map/reverse routine, thanks jwkrahn, and also jwkrahn's improvement to PreferredUserName's solution.

Rate Split Molt FAQ Cdarke PrefUN Jwkrahn Substr Split 7.85/s -- -16% -31% -41% -54% -70% -75% Molt 9.31/s 19% -- -19% -31% -45% -64% -70% FAQ 11.4/s 46% 23% -- -15% -32% -56% -63% Cdarke 13.4/s 71% 44% 17% -- -21% -48% -57% PrefUN 16.9/s 115% 81% 48% 26% -- -35% -45% Jwkrahn 25.9/s 230% 178% 126% 93% 53% -- -16% Substr 30.9/s 293% 231% 170% 130% 83% 19% --

Code in readmore tags revised,


In reply to Re: Formatting a number by johngg
in thread Formatting a number by harryf

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.