Re: How do I print a large integer with thousands separators?⭐
by davorg (Chancellor) on Oct 09, 2001 at 15:44 UTC
|
FAQ! Take a look at perlfaq5.
It references Number::Format, and also shows code for a regex and a subroutine, if you'd rather not use the module.
| [reply] |
Re: How do I print a large integer with thousands separators?⭐
by stefp (Vicar) on Oct 10, 2001 at 05:18 UTC
|
$number =~ s/(\d{1,3}?)(?=(\d{3})+$)/$1,/g;
The lookahead (?=(\d{3})+$) ensures that the number of digits before each underscore we insert is a multiple of 3.
An extra set of parentheses fools Perl because the regex parser barks when there are two quantifiers in a row, which is perfectly legitimate here.
This issue was also discussed in the thread Splitting every 3 digits?.
| [reply] [d/l] [select] |
|
To do it without capturing and resubstituting, you can add a lookbehind:
s/(?<=\d)(?=(?:\d{3})+\b)/$sep/g;
This also works:
substr($n, pos($n), 0) = $sep while ($n =~ /\d(?=(?:\d{3})+\b)/g);
As does:
substr($n, -($_*3 + ($_-1)*length($sep)), 0) = $sep for (1..int((lengt
+h($n)-1)/3));
| [reply] [d/l] [select] |
Re: How do I print a large integer with thousands separators?
by projekt21 (Friar) on Oct 09, 2001 at 15:31 UTC
|
| [reply] |
Re: How do I print a large integer with thousands separators?⭐
by dbwiz (Curate) on Jan 09, 2004 at 22:18 UTC
|
$number =~ s/(?<=\d)(?=(?:\d\d\d)+\b)/,/g;
| [reply] [d/l] |
Re: How do I print a large integer with thousands separators?
by Roger (Parson) on Jan 10, 2004 at 01:17 UTC
|
for ( $number )
{
/\./
? s/(?<=\d)(?=(\d{3})+(?:\.))/,/g
: s/(?<=\d)(?=(\d{3})+(?!\d))/,/g;
}
This says if the number has a decimal point,
end there for the purposes of commafication.
Otherwise, go to the end of the string.
| [reply] [d/l] |
Re: How do I print a large integer with thousands separators?
by Jaap (Curate) on May 17, 2005 at 11:36 UTC
|
my $number = 132452345;
for ( my $i = -3; $i > -1 * length($number); $i -= 4 )
{
substr( $number, $i, 0 ) = ',';
}
| [reply] [d/l] |
Re: How do I print a large integer with thousands separators?
by Anonymous Monk on Oct 24, 2004 at 23:38 UTC
|
For integers, one can avoid reverse as well as the repeated
substr derivation of the remaining string in the loop:
sub commafy_int
{
my $n = shift;
length($n) > 3 or return $n;
my $l = length($n) - 3;
my $i = ($l - 1) % 3 + 1;
my $x = substr($n,0,$i) . ',';
while ( $i < $l )
{
$x .= substr($n,$i,3) . ',';
$i += 3;
}
$x . substr($n,$i)
}
Not using reverse also makes it much easier to convert this to work
on floats (i.e. strings containing a decimal separator, '.').
To do so, simply replace any length calls above with
index($n.'.','.').
| [reply] [d/l] [select] |
Re: How do I print a large integer with thousands separators?
by jeroenes (Priest) on Oct 09, 2001 at 15:39 UTC
|
Modify $#, probably (see perlvar) or use sprintf.
Normally, perl prints without thousands separator. | [reply] |
|
Camel 3 has this on page 657:
$# [XXX,ALL] Don't use this; use
sprintf instead.
And on the previous page, "XXX" is defined as
meaning:
Deprecated, do not use in anything
new.
--
<http://www.dave.org.uk>
"The first rule of Perl club is you don't talk about
Perl club."
| [reply] |
|
In addition to the deprecatedness of $# mentioned by davorg,
how would you go about using sprintf to put thousands separators
into numbers? I don't see a simple way to do this - if there was it'd be
mentioned in the perlfaq to this topic, I'd guess.
-- Hofmator
| [reply] |
Re: How do I print a large integer with thousands separators?
by Anonymous Monk on Jan 31, 2004 at 05:11 UTC
|
I benchmarked the following methods
'while loop' is the "1 while..." method.
'reverse' is the Andrew Johnson method.
'lookahead' is the stefp method.
'manual' is the one using substr.
'le3manual' is the one using substr with an initial check to make sure there are more than three digits.
Number: | 3 | 2489 | 8x10^8 | 8x10^13 |
while loop: | 869k/s | 60k/s | 33k/s | 18k/s |
reverse: | 465k/s | 65k/s | 47k/s | 34k/s |
lookahead: | 571k/s | 54k/s | 34k/s | 22k/s |
manual: | 270k/s | 139k/s | 95k/s | 61k/s |
le3manual: | 1000k/s | 135k/s | 91k/s | 59k/s |
Nk/s = N thousands of completed commafications per second
Basically it looks like the substr method, with the <=3 clause, obliterates the competition. I feel dirty saying it, but looks like a one-liner regexp is not the best solution.
(My test script is available here) | [reply] |
|
Your test script was very educational for me. I'd never seen use of the Benchmark module before. It looks like you've certainly gotten a fast method for adding in the thousands separators.
For those who need something a bit easier to follow, I'd like to add the following to this topic:
#!/usr/bin/perl
use Number::Format;
my $num = 12349329824342;
my $nf = new Number::Format(-thousands_sep => ',');
my $separated_num = $nf->format_number($num);
| [reply] [d/l] |
Re: How do I print a large integer with thousands separators?
by hanspoo (Initiate) on Oct 26, 2004 at 23:44 UTC
|
$num = 123456789;
$num = reverse $num; # reverse the number's digits
$num =~ s/(\d{3})/$1,/g; # insert comma every 3 digits, from beginning
$num = reverse $num; # Reverse the result
$num =~ s/^\,//; # remove leading comma, if any
| [reply] [d/l] |
|
| [reply] |
Re: How do I print a large integer with thousands separators?
by Anonymous Monk on Aug 15, 2003 at 12:32 UTC
|
my $number = '$12345678.90'; # dollars
$_ = reverse $number;
s/(\d{3})(?=\d)(?!\d*\.)/$1,/g;
$number = reverse $_;
| [reply] [d/l] |
Re: How do I print a large integer with thousands separators?
by Anonymous Monk on Jan 09, 2004 at 15:13 UTC
|
sub puntato {
my $n=reverse($_[0]);
my $x='';
while(length($n)>3) {
$x=$x.substr($n,0,3).'.';
$n=substr($n,3);
}
$x=reverse($x.$n);
return($x);
}
| [reply] [d/l] |
|
sub puntato{ my $z=reverse $_[0];$z=~s/(\d{3})(?=\d)/$1\./g;scalar(rev
+erse($z))}
| [reply] [d/l] |
Re: How do I print a large integer with thousands separators?
by hdb (Monsignor) on May 27, 2013 at 19:05 UTC
|
$number = 123456789;
$number = reverse join ",", (reverse $number) =~ /(\d{1,3})/g;
| [reply] [d/l] |