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

I'm trying to understand the rounding function in the floating point notation. Rounding to the nearest interger seems to work according to documentation with x.50 rounding up if x is odd and truncating if x is even. The difficulty I'm having arises when I round to the tenths place with something like - $rounded=sprintf ("%.1f",$r); I get the following results: 3.05 is 3.0, 3.15 is 3.1, 3.25 is 3.2, 3.35 is 3.4, 3.45 is 3.5, 3.55 is 3.5, 3.65 is 3.6, 3.75 is 3.8, 3.85 is 3.9, 3.95 is 4.0. I realize I could write a subroutine to do it correctly, but I really would like to know what's going on. Any ideas? Thanks

Replies are listed 'Best First'.
Re: Rounding
by Zaxo (Archbishop) on Sep 23, 2002 at 03:54 UTC

    See perlfaq4 for why this happens, decimal fractions are not exactly representable in binary.

    What you want is called banker's round. It tends to minimize cumulative errors, as well as giving a useful surplus of even numbers.

    After Compline,
    Zaxo

Re: Rounding
by riffraff (Pilgrim) on Sep 23, 2002 at 13:00 UTC
    That is the problem with floating point. Computers don't do to well with it. See this node for more information.
Re: Rounding
by uwevoelker (Pilgrim) on Sep 23, 2002 at 09:13 UTC
    $rounded=sprintf ("%.1f",$r+.05);
    This solves your problem :-)
      That causes 1.3 to be rounded to 2.0. I don't believe that's what the poster wanted.

      Makeshifts last the longest.

        No, it does not.
        I ran
        $r = 1.3; print $r,"\n"; $rounded=sprintf ("%.1f",$r+.05); print $rounded,"\n";
        and got
        perl -w round.pl 1.3 1.4
        Did you miss a 0 after the decimal? or is there some other behaviour I a missing.