# printf: zero pad after the decimal a given amount

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
Why is there no way to tell printf to zero pad like the right column:
0.1    :0.100
0.05   :0.050
0.03   :0.030
0.025  :0.025
0.02   :0.020
0.015  :0.015
0.0125 :0.0125
0.01   :0.010
0.009  :0.009
0.00625:0.00625
0.005  :0.005
The challenge: Change only the "WHAT?" below to produce the right
column above. Thanks.
use constant S => 100000;
for ( 10000, 5000, 3000, 2500, 2000, 1500, 1250, 1000, 900, 625, 500 ) {
printf "%-7g:WHAT?\n", \$_ / S, \$_ / S;
}

## Re: printf: zero pad after the decimal a given amount

jidanni@jidanni.org wrote:

\$ perl -le'
use constant S => 100000;
my \$x;
format =
@<<<<<< : @.#####
\$x,       \$x
.
for ( 10000, 5000, 3000, 2500, 2000, 1500, 1250, 1000, 900, 625, 500 ) {
\$x = \$_ / S;
write;
}
'
0.1     : 0.10000
0.05    : 0.05000
0.03    : 0.03000
0.025   : 0.02500
0.02    : 0.02000
0.015   : 0.01500
0.0125  : 0.01250
0.01    : 0.01000
0.009   : 0.00900
0.00625 : 0.00625
0.005   : 0.00500

John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order.                            -- Larry Wall

## Re: printf: zero pad after the decimal a given amount

jidanni@jidanni.org wrote:

use constant S => 100000;
for ( 10000, 5000, 3000, 2500, 2000, 1500, 1250, 1000, 900, 625, 500 ) {
printf "%-7g:%01d.%3.3s%s\n", \$_ / S, int \$_ / S,
sprintf("%05d", \$_),
map { \$_ ? \$_ : '' } (\$_ % 100) =~ m!^(\d+?)0*\$!;
}

__OUTPUT__
0.1    :0.100
0.05   :0.050
0.03   :0.030
0.025  :0.025
0.02   :0.020
0.015  :0.015
0.0125 :0.0125
0.01   :0.010
0.009  :0.009
0.00625:0.00625
0.005  :0.005

:-)

--
szr

## Re: printf: zero pad after the decimal a given amount

On Mar 30, 4:09=A0pm, jida...@jidanni.org wrote:

Why do you assume that because you don't know the way, there is no
way?

%.03f

\$ perl -e'printf("%.03f\n", .1)'
0.100

Paul Lalli

## Re: printf: zero pad after the decimal a given amount

Paul Lalli wrote:

Actually that truncates to 3 decimal places, which isn't what the op
required:

\$ perl -e'printf("%.03f\n", .00625)'
0.006

See my other post for a working solution.

--
szr

## Re: printf: zero pad after the decimal a given amount

szr wrote:

s/truncates/rounds/;

The 0 in .03 is useless.

Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de /
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

## Re: printf: zero pad after the decimal a given amount

jidanni@jidanni.org schreef:

\$ perl -wle'
print "".reverse sprintf "%05.1f", "".reverse sprintf "%f", \$_
for qw/.1 .05 .03 .025 .02 .015 .0125 .01 .009 .00625 .005
1.987654321E1/
'
0.100
0.050
0.030
0.025
0.020
0.015
0.0125
0.010
0.009
0.00625
0.005
9.876543

;)

--
Affijn, Ruud

"Gewoon is een tijger."

## Re: printf: zero pad after the decimal a given amount

Dr.Ruud wrote:

And how do you deal with negative numbers and numbers >= 10? ;)

Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de /
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

## Re: printf: zero pad after the decimal a given amount

Frank Seitz schreef:

Hey! There were only numbers in [0..1>, so I already extended it to
[0..10>.

Oh well,

perl -wle'
\$n=length(int abs),
print+(\$_<0?"-":"").reverse sprintf"%0*.*f",\$n+4,\$n,
"".reverse sprintf"%f",abs
for qw/0 .1 .05 .03 .025 .02 .015 .0125 .01 .009 .00625 .005
1234567.89 -9876543.21/
'
0.000
0.100
0.050
0.030
0.025
0.020
0.015
0.0125
0.010
0.009
0.00625
0.005
1234567.890
-9876543.210

--
Affijn, Ruud

"Gewoon is een tijger."

## Re: printf: zero pad after the decimal a given amount

jidanni@jidanni.org wrote:

One reason is that what you want is ill-defined.  If we are going to tweak
sprintf to make it suit our personal preferences, I'd rather see a
conversion character that behaved just like %f if given a good number, but
returned the empty string if given either an empty string or undef (rather
than converting it to zero and then applying %f to the zero.)

Apparently you want to preserve non-zero digits even if that means going
beyond 3 digits right of the decimal.  But why did you stop at 4?

0.014999999999999999444888

0.0125000000000000006938893

How many consecutive zeros or nines are needed before you decide there are
enough to ignore what is the right of them?

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

## Re: printf: zero pad after the decimal a given amount

Quoth xhoster@gmail.com:

It appears to me the OP wants either 3 s.f. after the point or 3 places,
whichever comes out shorter. Something like

sub fmt {
return
map /(\d*\.\d\d*?)0*\$/,
map /(\d*\.0*[1-9]\d\d)/,
map { sprintf "%.308f", \$_ }
@_;
}

appears to work, but it's hardly pretty :(. The 308 is the number of
places required to represent DBL_MIN with 53-bit doubles; if your perl
is using 64-bit long doubles you will need 4932 instead.

Ben

## Re: printf: zero pad after the decimal a given amount

BM> It appears to me the OP wants either 3 s.f. after the point or 3 places,
BM> whichever comes out shorter. Something like

BM>     sub fmt {
BM>         return
BM>             map /(\d*\.\d\d*?)0*\$/,
BM>             map /(\d*\.0*[1-9]\d\d)/,
BM>             map { sprintf "%.308f", \$_ }
BM>             @_;
BM>     }

BM> appears to work, but it's hardly pretty :(. The 308 is the number of
BM> places required to represent DBL_MIN with 53-bit doubles; if your perl
BM> is using 64-bit long doubles you will need 4932 instead.

Is there any harm in always using 4932?  I would guess not, except maybe
for wasted CPU cycles.

Ted

## Re: printf: zero pad after the decimal a given amount

Hi, it's me, the Original Poster. Thanks for all the replies. Mr.
Krahn employed [perlform - Perl formats], but did not check if he
produced the required results. User srz followed with a map()
solution, but my screensaver kicked in before I could figure it out
staring at it so long :-) The solution employing reverse() indeed blew
up on different input. The remaining map() solutions I will study later.

OK, this gives me what I want in the right column it makes,
and is not obfuscated to me:

use constant S     => 10000000;
for (
1000000, 500000,        300000,       250000, 200000,
150000,  125000,        100000,       90000,  62500,
50000,   1.987654321E1, 777700000000, -44,    -660000000
)
{
for ( \$_ / S ) {
printf "%-7g:", \$_;
\$_ = sprintf "%f", \$_;
/.*\.\d(.*[^0])?/;
print "\$&\n";
}
}

OK, it seems like I accept some truncation for tiny numbers.

Mainly what is bothering me about %g and %f is that apparently they
don't make full use of what they could have, if implemented.

e.g., %-#05.-#03f or something, whatever that would mean. Or at least
%-05.03f etc. What I'm saying is %f and/or %g are like when you
parents chose the two door sedan instead of the four door model that
it could have been, with all the bells and whistles.

Now if it is appropriate to add more creeping features to %f or %g at
this "late stage" is another question. P.S., %g is particular squishy,
turning into "e" notation if fed caterpillars, etc. Scary.