Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Zero Padding to the Right of the Decimal

by Anonymous Monk
on Jan 15, 2004 at 16:09 UTC ( #321592=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks:
The following code results in a loss of zero padding to the right of the decimal.
code snippet below:
my $i=0; while ($i <=100){ $i=sprintf("%3.2f",$i); $i=$i+0.01; print "$i\n"; }
Snippet of the Actual Output:
99.9 99.91 99.92 99.93 99.94 99.95 99.96 99.97 99.98 99.99 100
What I would like to see is:
99.90 99.91 99.92 99.93 99.94 99.95 99.96 99.97 99.98 99.99 100.00
What subtlety am I missing?
I am running Active Perl 5.8.2 Build 808 on Windows 2000.

Replies are listed 'Best First'.
Re: Zero Padding to the Right of the Decimal
by davido (Archbishop) on Jan 15, 2004 at 16:17 UTC
    You just have the order of things mixed up a little. Here's what you have:

    my $i=0; while ($i <=100){ $i=sprintf("%3.2f",$i); $i=$i+0.01; print "$i\n"; }

    So you turn $i into a string with padding, and then you increment by 0.01, which causes Perl to coerce the string into a number. At that point, string formatting is lost, and you get Perl's default numeric formatting. You could correct the problem by eliminating the sprintf and turning your print into printf, or simply increment $i before the sprintf statement instead of after, so that the effect sprintf has of coercing a value into a string isn't lost prior to the print.

    Smile! Most languages don't even let you coerce strings into numeric values, and back again, without using two different variables and a conversion function. Perl does its best at Doing What You Mean.

    Hope this helps.


      Although I knew the answer to this one (believe me they are far and few between, but I keep trying ;-}), the above node is OUTSTANDING. ++ to you davido. I wish more monks took the time to answer like this.


Re: Zero Padding to the Right of the Decimal
by jmcnamara (Monsignor) on Jan 15, 2004 at 16:19 UTC

    On this line you are converting the number to a string:
    But on the following line you convert it back to a number*:
    So either do the increment before you do the sprintf or else just use printf:
    printf "%3.2f\n", $i;


    * Internally it will be both a number and a string.

      I agree whole-heartedly, the number probably shouldn't be baked into a format until you plan to display it. <insert standard disclaimer about being appropriate for the rest of your script and your coding style>

      So it might look like this with only one print/printf/sprintf:

      my $i=0; while ($i <=100){ $i=$i+0.01; printf("%3.2f\n",$i); }


        Just one more thing, how about this:

        printf( "%3.2f\n" , ($i + 0.01) );

        Instead of the two lines above?

        =~y~b-v~a-z~s; print
Re: Zero Padding to the Right of the Decimal
by revdiablo (Prior) on Jan 15, 2004 at 22:03 UTC

    One thing I did not see mentioned in the preceeding answers to your question is that the 3 in %3.2f is pointless. Perhaps you were attempting to pad the LHS of the decimal to 3 places? This would be accomplished with %6.2f. Note that the number to left of the decimal is how much to pad the entire thing, not just the LHS.

    Also, not to toot my own horn, but the entire construct can be reduced to a single line of code:

        printf "%6.2f\n", $_/100 for 0 .. 100*100;
Re: Zero Padding to the Right of the Decimal
by Anonymous Monk on Jan 15, 2004 at 17:41 UTC
    I knew it had to be a subtlety!
    Thank you all for your Wisdom ! :)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://321592]
Approved by gri6507
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2016-10-25 10:58 GMT
Find Nodes?
    Voting Booth?
    How many different varieties (color, size, etc) of socks do you have in your sock drawer?

    Results (317 votes). Check out past polls.