Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Rounding problem with sprintf??

by Anonymous Monk
on Jul 03, 2001 at 00:06 UTC ( [id://93305]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Is there a problem with sprintf when rounding on exactly .5
Below is my code:
$a = 2.815; $a = sprintf("%.2f", $a); printf "a =".$a."---\n";
Result: 2.81
Shouldn't it show 2.82? What can I do to get around this?
Is this a known problem with perl?
Any help is much appreciated!

Replies are listed 'Best First'.
Re: Rounding problem with sprintf??
by japhy (Canon) on Jul 03, 2001 at 00:46 UTC
    This is a known "bug". It happens like that in C as well. Write your own rounding function, or use this one:
    # round(789.456,-2) => 800 # round(789.456,-1) => 790 # round(789.456) => 789 # round(789.456,1) => 789.5 # round(789.456,2) => 789.46 sub round { my ($n, $p) = @_; my $sign = ($n > 0) ? 1 : -1; $p ||= 0; $n *= 10 ** $p; $n = int($n + .5 * $sign); return $n / 10**$p; }


    japhy -- Perl and Regex Hacker

      This sub has the same bug as sprintf.

      round(5.245,2) returns 5.25

      but

      round(9.325,2) returns 9.32

Re: Rounding problem with sprintf??
by Anonymous Monk on Jul 03, 2001 at 00:22 UTC
    2.815 can not be precisely represented by a floating point number
    printf("%.20f\n", 2.815);
Re: Rounding problem with sprintf??
by Aighearach (Initiate) on Jul 03, 2001 at 00:23 UTC
    No, I don't think this is a problem, as for it to be a problem in perl that would require .5 to evaluate as > .5. That is, if it is _over_ half then it will round, and otherwise it will truncate. It has to go one way or the other, neither way is really right or wrong.

    The good news is, add a very small number like .000001 and you'll get what you want.

    $a = sprintf("%.2f", $a+.00001);

    --
    Snazzy tagline here
Re: Rounding problem with sprintf??
by tadman (Prior) on Jul 03, 2001 at 00:25 UTC
    Update:
    Just look down at what ChemBoy wrote and forget I ever said anything. Must be one of those days.
      The default behaviour for routines like this is to round down to the nearest number, much like int() does for integers. As a result, rarely does any rounding occur in any Perl or C routines on which Perl is based, such as sprintf.

      I don't think this is true, tadman. Testing:

      % perl -e 'printf "%1.2f\n", 1.234' 1.23
      and
      % perl -e 'printf "%1.2f\n", 1.235' 1.24

      Which gives me to think that rounding does in principle occur in sprintf and printf. The problem is the floating point representation of base-10 numbers, which occasionally gives you less precision than you though you had. If you really need that precision, hunt around for further discussion on the issue using Super Search, and you'll find plenty.

      Update: or just read japhy's response on the original thread.



      If God had meant us to fly, he would *never* have give us the railroads.
          --Michael Flanders

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://93305]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-03-28 22:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found