Rounding Bug in Python 2.0! - ugh

Thomas Wouters thomas at xs4all.net
Tue Oct 31 16:41:53 EST 2000


On Tue, Oct 31, 2000 at 04:10:20PM -0500, Gordon Williams wrote:

> When I switched from python 1.5.2 to 2.0 final I had a surprise in some code
> that was working previously.

> It comes down to:
> >>> x=3.8999999999999999
> >>> round(x,3)
> 3.8999999999999999
> >>>

> >>> x=3.123456
> >>> round(x,3)
> 3.1230000000000002

> Someone is going to start talking about machine round off errors, but this
> is a BIG UGH!!

Is it really ? The *only* difference here is that the interactive
interpreter now shows the floating point value as closely as expected.
Nothing about the *return value* of round() changed.

> It is not what is intuitively expected.  Can we go back to the good old days
> when 1.5.2 lied to us and gave us the answer that we expect and need!!

It has nothing, absolutely nothing, to do with 2.0 or 1.5.2. It doesn't have
anything to do with rounding, either. It has everything to do with
approximation, and the fact that some floating point values cannot be
expressed in a specific floating point format. Trust me. If you want to see
the old behaviour, try using 'str()' on the return value of round:

>>> x = 3.8999999999999999
>>> str(round(x,3))
'3.9'

What happens is that 'round' grabs 'x', which is approximately
3.8999999999999999, tries to 'round' it to 3.899, and returns the floating
point value that comes closest to that. But the problem is,
3.8999999999999999 *is* the closest thing to 3.899 the machine can supply. 

This is exactly how it behaved in 1.5.2, but you probably didn't notice,
because 'str()' does rounding to 'sane' numbers. The difference between 2.0
and 1.5.2 is that 'repr()' used to do the same rounding as 'str()', and no
longer does. 'repr()' is supposed to give as detailed information as
possible, so it should show as many digits as is feasible.

If you want to know *why* most machines can't approximate 3.899 better, buy
a book that explains IEEE floating point :) O'Reilly's "High Performance
Computing" does an excellent job, for instance.

In short, don't use 'repr()' if you don't *want* an exactest-possible
representation of a value :)

Gosh-now-I-know-what-Tim-must-feel-like-when-people-ask-him-about-FP-ly
	y'rs, ;)
-- 
Thomas Wouters <thomas at xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!




More information about the Python-list mailing list