Rounding curiosity

P

PyBo

What's wrong with this picture?
476.83999999999997

I have tried this and get the same result using different CPU's and operating systems.
Obviously, '476.83999999999997' is not rounded to two decimal places.

Or am I doing something wrong?
 
G

Grant Edwards

What's wrong with this picture?

Wrong is in the mind of the beholder. ;)
476.83999999999997

I have tried this and get the same result using different
CPU's and operating systems.

There's a reason for that:

http://www.python.org/doc/faq/general.html#why-are-floating-point-calculations-so-inaccurate
http://docs.python.org/tut/node15.html
Obviously, '476.83999999999997' is not rounded to two decimal
places.

Of course it isn't. Computers don't use decimal. They use
binary: aye, there's the rub...
Or am I doing something wrong?

You're using binary floating point math without understanding
it. If you tell us what you're actually trying to accomplish,
we can probably tell you how to do it.

If you're just worried about how it looks on the screen:
476.84

If you want the computer to fib for you, it will. :)
 
G

Ganesan R

Tim" == Tim Peters said:
What's wrong is that you haven't yet read the Python tutorial's
appendix on floating-point issues. That much is easily repaired
<wink>:

IMHO the documentation for round() function is misleading in this
respect. It reads

====
round(x[, n])
Return the floating point value x rounded to n digits after the decimal
point. If n is omitted, it defaults to zero. The result is a floating
point number. Values are rounded to the closest multiple of 10 to the
power minus n; if two multiples are equally close, rounding is done away
from 0 (so. for example, round(0.5) is 1.0 and round(-0.5) is -1.0).
====

Something like, "Note that, since the floating point values cannot represent
decimal fractions exactly, the rounding will not be exact." should help.

Ganesan
 
P

PyBo

Grant said:
Wrong is in the mind of the beholder. ;)




There's a reason for that:

http://www.python.org/doc/faq/general.html#why-are-floating-point-calculations-so-inaccurate
http://docs.python.org/tut/node15.html




Of course it isn't. Computers don't use decimal. They use
binary: aye, there's the rub...




You're using binary floating point math without understanding
it. If you tell us what you're actually trying to accomplish,
we can probably tell you how to do it.

If you're just worried about how it looks on the screen:



476.84

If you want the computer to fib for you, it will. :)
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?

By the way,
print "%0.2f" % (5e8/(1024*1024))
yields the same result as
print "%0.2f" % round(5e8/(1024*1024),2)
so the 'round()' portion of the expression is superfluous.
 
T

Tim Peters

[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:
476.83999999999997

Or, without any obfuscating convolutions, simply this:
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>.
 
D

Donn Cave

Grant Edwards said:
If you're just worried about how it looks on the screen:

476.84

If you want the computer to fib for you, it will. :)

Actually it will anyway - once you use "print", you
get a str() automatically, and that rounds off in a
way that happens to give you the same result in this
case - so the formatting above is superfluous unless
the occasional trailing zero is important. If repr()
did the same, we'd hear a lot less of this.

Donn Cave, (e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top