Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

strange rounding

by Anonymous Monk
on Nov 29, 2004 at 12:24 UTC ( #410904=perlquestion: print w/replies, xml ) Need Help??

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

Hi, to round decimals numbers to a price (2 dec)
I have
my $p = &PricePerUnit(..); $units = int(0.5 + ($units*$p*100) )/100;
As I always got like 123.99, but I don't want 'super-market-prices'!
I 'explode' this calc and I found
int(0.5 + ($units*$p*100) ) => 12400 (ok!!) but now deviding 12400 by 100 I get 123.99 instead of 124.00 or 124
What is my mistake? The accepted non-accuracy can't be that big?


Replies are listed 'Best First'.
Re: strange rounding
by bart (Canon) on Nov 29, 2004 at 13:06 UTC
    Oh no, not that FAQ again.

    Anyway, the best way to round to two decimals, is using sprintf:

    $units = sprintf "%.2f", $units*$p;
    In case you don't like trailing zeroes (maybe you do), as in "124.00", you can get rid of them using
    $units =~ s/\.?0+$//;
    turning "123.50" into "123.5", and "124.00" into "124".

    Only do this when you know your number contains a decimal point.

      I have found Math::Round a great package for rounding.

      $perl -MMath::Round -e "print nearest(0.01, 3.14159)" 3.14

      "Look, Shiny Things!" is not a better business strategy than compatibility and reuse.

Re: strange rounding
by reneeb (Chaplain) on Nov 29, 2004 at 13:06 UTC
      I first unsuccessfuilly serached for int(), because I could not imagine
      that the division of 100 causes this,
      second I thought, that other must have been unpleased as well.

      Finally I want to let you know that even

      $u = sprintf "%.2f", (int(0.5+($u*$p*100))/100);
      produces 123.99 and not 124.00. Only Math::Round had the correct answers.


        Try this:

        print int(0.500000000000001+($u*$p*100))/100;

        Examine what is said, not who speaks.
        "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
        "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: strange rounding
by edan (Curate) on Nov 29, 2004 at 12:56 UTC
Re: strange rounding
by I0 (Priest) on Dec 01, 2004 at 07:13 UTC
    What are $units and $p when you do this?
    I only get 123.99 when int(0.5 + ($units*$p*100) ) == 12399
Re: strange rounding
by Anonymous Monk on Nov 29, 2004 at 12:39 UTC
    btw, even
    12400/10 => 1239.9 ?? and 12400*0.1 => 1239.9
    having stange results. But PLEASE don't tell me that I have to convert
    those numbers into strings and re-formate them (like):
    s/(\d*)(\d\d)/$1.$2/ or $price = substring(..).'.'.substr(..) (I asume that s/../../ is exactly doing this)

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2020-10-30 05:48 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (278 votes). Check out past polls.