in reply to Proper monetary rounding

The built-in sprintf implements round-to-even already:
for (qw(1.0049 1.0050 1.0051 1.0149 1.0150 1.0151 1.0249 1.0250 1.0251 +)) { printf "%s => %0.2f\n", $_, $_; } ... 1.0049 => 1.00 1.0050 => 1.00 1.0051 => 1.01 1.0149 => 1.01 1.0150 => 1.01 1.0151 => 1.02 1.0249 => 1.02 1.0250 => 1.02 1.0251 => 1.03
Hmm. Why didn't that work? {grin}

Replies are listed 'Best First'.
Re^2: Proper monetary rounding
by blogical (Pilgrim) on Mar 05, 2007 at 03:43 UTC

    That's what I had been doing, until I heard that accountants are actually picky about this sort of thing.

    "Round to even" considers the case where the number just past the least significant is a 5, followed only by zeroes. It then rounds odd LSDs up to the nearest even, rounding off even LSDs.

      I think he's saying that sprintf actually does that, in just that way:

      perl -e 'my $x = 1.5050; my $y = 1.5150; my $s = sprintf "%0.2f\n%0.2f +\n", $x, $y; print $s;' 1.50 1.52

      "Normal" (gradeschool) rounding would produce 1.51 and 1.52 there, but sprintf says 1.50 and 1.52, which seems an aweful lot like round-to-even to me. How does it differ from what you wanted?

      As far as accountants being picky about this... have you ever seen the movie Superman 3?

      -- 
      We're working on a six-year set of freely redistributable Vacation Bible School materials.
        Are you sure that's sprintf behaviour, or is there a limitation in the IEEE floating point representation of 1.5050 that has it leaning on the low side of 0.0050? That's the only explanation I can think of as to why sprintf would be broken like this.

        printf("%0.2f\n", $_) for 1.4050, 1.5050, 1.6050, 1.7050; seems to indicate this only works for 1.5... or am i missing a bigger picture here?


        ___________
        Eric Hodges