Hacker News new | ask | show | jobs
by kccqzy 381 days ago
> First of all, a lot of languages don't include arbitrary rounding in their math libraries at all, only having rounding to integers.

You do the simple, obvious and correct thing: multiply by 100, round to int, convert to double, divide by 100. It does not matter whether the final division by 100 results in an exact value. (You might argue this is inefficient but it's not a correctness problem.)

> for example, round(2.675, 2) gives 2.67 instead of the expected 2.68.

You are not going to execute round(2.675, 2) if you follow my advice of rounding after every operation. Because the error will never reach 0.005. Your argument is moot.

1 comments

You can certainly encounter 2.675 as a multiplier, even if you wouldn't have it as a balance.

It doesn't matter that some error starts off way less than 0.005 if rounding then amplifies it. We can find two 2-digit numbers that multiply to get exactly 2.675 in reals, but whose product differs from the float number closest to 2.675 enough to affect rounding:

    abs(      2.14 * 1.25     -       2.675    ) < 0.005
    abs(round(2.14 * 1.25, 2) - round(2.675, 2)) > 0.01
And regarding integer vs fractional rounding, we can see different results for what is nominally the same computation, depending on where the decimal point is:

    abs(round(1.0  * 1.5, 0) - 2.0 ) < 0.1
    abs(round(0.01 * 1.5, 2) - 0.02) > 0.001
Now, I never said that floats were bad. I am only saying that rounding them doesn't work the way one might expect, and shouldn't be done any more than necessary; in many cases, it's not necessary at all.