Rounding curiosity

Tim Peters tim.peters at gmail.com
Wed Nov 17 01:51:21 EST 2004


[PyBo]
> To all those who are feeling so smug and superior, perhapts you could
> have noticed that I was pointing out that the round() function does not
> perform as documented?

Hmm.  You didn't mention the documentation.  Really.  You mentioned
"different CPU's and operating systems", and you mentioned that

    Obviously, '476.83999999999997' is not rounded to two decimal
    places.

That's the point you were missing:  it is in fact rounded to two
decimal places, to the very best that is possible to do using your
hardware's binary float arithmetic.  If you truly need to be told,
then math.sqrt() doesn't compute exact square roots either, and infix
"+" applied to floats doesn't compute exact sums either, and ... etc. 
There's nothing special about round() here.

Try doing it "by hand" and you'll get the same result:

>>> int(5e8/1024**2 * 100.0 + 0.5) / 100.0
476.83999999999997

Or, without any obfuscating convolutions, simply this:

>>> 476.84
476.83999999999997

The decimal number 476.84 cannot be represented exactly using binary
fp -- it's impossible to get the result you expected.  This phenomenon
is pervasive, affecting all functions and operations producing floats,
not specific to round() -- so even if you had actually been talking
about round's documentation, it still would have been most helpful to
give you the references you were given, discussing the *general*
issue.  round() behavior is just a little pimple on binary fp's big,
fat butt <wink>.



More information about the Python-list mailing list