Re: Zero Padding
by chipmunk (Parson) on Feb 03, 2001 at 01:10 UTC
|
You can do this just using sprintf:
$padded = sprintf "%06d", 13;
The zero after the percent sign says to pad with zeros instead of spaces. | [reply] [d/l] |
Re: Zero Padding
by autark (Friar) on Feb 03, 2001 at 01:10 UTC
|
Well, printf works fine as long as you find the right
template:
printf("%06d", 13);
Autark.
| [reply] [d/l] |
Re: Zero Padding
by runrig (Abbot) on Feb 03, 2001 at 01:12 UTC
|
This is one area where the perldocs don't help much. But on most *nix systems you can 'man printf' or 'man sprintf' to get the relevant docs. Or find online Unix man pages.. or just give you the answer: 'printf("%06d", $variable)'
Ok, so I'm wrong, you can now find the relevant info with 'perldoc -f sprintf' or even here: sprintf. | [reply] |
Re: Zero Padding
by footpad (Abbot) on Feb 03, 2001 at 09:07 UTC
|
| [reply] |
Re: Zero Padding
by dystrophy (Monk) on Feb 03, 2001 at 06:27 UTC
|
If you had done a search, you probably would have come up with Padding Out Strings, although this discussion went a tad deeper then that one.
There are other uses for padding zeros than homework you know. Image frame numbers for instance - the padded zeros help OSs list the frames in the correct order. (speaking from experience, having written innumerable little scripts that do strange and wonderful things to a large number of frames)
- dystrophy - | [reply] |
Re: Zero Padding
by mkmcconn (Chaplain) on Feb 03, 2001 at 22:40 UTC
|
Variation on a theme, with a twist that I don't think has
been mentioned. I've tried to do my homework, and nothing stood out that would break this. What do you think?
#!/usr/bin/perl -wl
use strict;
my @numberarray = qw(1 120 13);
lengthy(@numberarray);
sub lengthy {
s{
( ^ )
}
{
( "0" x (6-length $_) )
}xe and print for @_;
}
__END__
Or, for the commandline:
perl -wle ' s/^/("0"x(6-length))/xe and print for @ARGV;' 133 121 10 13
Or, to make sure that it doesn't zero-pad alphabetical input
perl -wle ' s{(^)(\d+$)}{("0"x(6-length).$2)}xe and print for @ARGV;' 1 fish 002 fish 333 blue fish
And, to print all the arguments, but zero-padding
only the numerical arguments:
perl -wle ' s{(^)(\d+$)}{("0"x(6-length).$2)}xe and print or print for @ARGV;' 1 fish 002 fish 333 blue fish
(Sir...put your hands up and please, step away from the keyboard)
One more.. to pad words with spaces, instead of zeros.
perl -wle ' s/^(\d+)/("0"x(6-length).$1)/xe and print or
s/^(\w)/("\x20"x(6-length).$1)/xe and print for @ARGV;' 133 121 10
+ 13 red
mkmcconn
(I'm gratified by how
much better it is than this a few short
weeks later. Thanks Perl Monks.).
| [reply] [d/l] [select] |
Re: Zero Padding
by tune (Curate) on Feb 03, 2001 at 03:37 UTC
|
And if you dont want to use printf()/sprintf() because it slows your script down just work it out by yourself:
#!/usr/bin/perl
$a=13;
$length=6;
while (length($a)<$length) {$a="0$a";}
print $a;
--
tune | [reply] [d/l] |
|
A quick Benchmark will show that this repeated concatenation is slower than sprintf:
#!/usr/local/bin/perl
use Benchmark;
my $var=13;
my $length=6;
timethese(100000, {
CONCAT=>\&concat,
SPRINTF=>\&spr_f,
});
sub concat {
my $a = $var;
while (length($a)<$length) {$a="0$a";}
}
sub spr_f {
my $a = $var;
sprintf("%0$length", $a);
}
Results:
Benchmark: timing 100000 iterations of CONCAT, SPRINTF...
CONCAT: 2 wallclock secs ( 1.53 usr + 0.00 sys = 1.53 CPU) @ 65
+359.48/s (n=100000)
SPRINTF: 0 wallclock secs ( 0.60 usr + 0.00 sys = 0.60 CPU) @ 16
+6666.67/s (n=100000)
UpdateOops, fixed the bug, tye's right that it doesn't change the result much, but I didn't really want to return the correct value in concat() or make spr_f() extra fast, just wanted to compare the process to create the desired result. | [reply] [d/l] |
|
You had a bug in spr_f() (you end up using a format of "%06" instead of "%06d"). That didn't seem to affect the speed much, though. You also don't return the correct value from concat() so I fixed that too. I made spr_f() a bit faster by eliminating the extra copy. This penalizes concat() since it is now the only one that needs the extra copy (oh well).
I added my favorite (that I learned from chip) and reran the benchmark:
#!/usr/bin/perl -w
use strict;
use Benchmark qw( cmpthese );
my $num= 13;
my $wid= 6;
sub concat {
my $a= $num;
$a= "0$a" while length($a) < $wid;
$a;
}
sub spr_f {
sprintf( "%0${wid}d", $num );
}
sub sub_s {
substr( "0"x$wid.$num, -$wid );
}
cmpthese( -3, {
CONCAT => \&concat,
SPRINTF => \&spr_f,
SUBSTR => \&sub_s,
});
__END__
Your Results:
Benchmark: timing 100000 iterations of CONCAT, SPRINTF...
CONCAT: 65359.48/s
SPRINTF: 166666.67/s
Mine: Rate CONCAT SPRINTF SUBSTR
CONCAT 98370/s -- -62% -66%
SPRINTF 257009/s 161% -- -10%
SUBSTR 286165/s 191% 11% --
Looks like the substr() is fastest.
-
tye
(but my friends call me "Tye") | [reply] [d/l] [select] |
|
|
|
True, but it should be obvious without pulling out
Benchmark that the algorithm is quadratic. Just look at
how much recopying of data there is.
*shrug*
| [reply] |
|
try this
$foo = 0000
$foo .= $number
| [reply] |
|
|
tune: while (length($a)<$length) {$a="0$a";}
Humm.. why use a while loop. Wouldn't this be faster?
$number = '0' x (5 - length($number)) . $number;
// Martin
| [reply] [d/l] [select] |
Re: Zero Padding
by ftforger (Sexton) on Feb 03, 2001 at 03:54 UTC
|
Sounds an awful lot like a high school homework
project to me. (Or part of one at least) | [reply] |
|
Maybe, but the seeker didn't just copy and past the assignment, like some others. He asked for the best way to perform a very specific task, and demonstrated that he had read the docs enough to know that (s)printf was the right function to use, and even had a working, though suboptimal solution. A "this is homework" disclaimer is always nice, but I think this post is ok without it (even assuming it is homework).
--
Ryan Koppenhaver, Aspiring Perl Hacker
"I ask for so little. Just fear me, love me, do as I say and I will be your slave."
| [reply] |
Re: Zero Padding
by Yoda (Sexton) on Feb 04, 2001 at 17:43 UTC
|
Ok, Something short and quick
$num = 13;
$len = 6;
$padnum = 0 x ($len - length($num)) . $num;
Yoda | [reply] [d/l] |
|
I posted a similar solution here, but with one difference - the 0 was quoted.
At first glance, you might think "So what?", but in benchmarks it actually was 25% faster than the unquoted version.
I assume this is because perl has to do less work to figure out the context of 0 and transform it into a string.
| [reply] |