printf: zero pad after the decimal a given amount

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;
}
Dan Jacobson [ So, 30 März 2008 22:09 ] [ ID #1933259 ]

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

jidanni [at] jidanni.org wrote:
> 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;
> }

$ perl -le'
use constant S => 100000;
my $x;
format =
[at] <<<<<< : [at] .#####
$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
someone [ Mo, 31 März 2008 07:24 ] [ ID #1933263 ]

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

jidanni [at] jidanni.org wrote:
> 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;
> }

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
szr [ Mo, 31 März 2008 10:23 ] [ ID #1933272 ]

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

On Mon, 31 Mar 2008 21:55:16 +0100 Ben Morrow <ben [at] morrow.me.uk> wrote:

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{3}\d*?)0*$/,
BM> map /(\d*\.0*[1-9]\d\d)/,
BM> map { sprintf "%.308f", $_ }
BM> [at] _;
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
Ted Zlatanov [ Di, 01 April 2008 15:35 ] [ ID #1933299 ]

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{3}(.*[^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.

> The 0 in .03 is useless.

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.
Dan Jacobson [ Mi, 02 April 2008 04:40 ] [ ID #1934184 ]
Perl » comp.lang.perl.misc » printf: zero pad after the decimal a given amount

Vorheriges Thema: Re: printf: zero pad after the decimal a given amount
Nächstes Thema: TieRegistry with IPConfig