[Tutor] very odd math problem
Steven D'Aprano
steve at pearwood.info
Fri Mar 11 06:05:34 CET 2011
Alex Hall wrote:
> Hi all,
> I am trying to get a list of ordered pairs from the below function. In
> my code, evaluate is more exciting, but the evaluate here will at
> least let this run. The below runs fine, with one exception: somehow,
> it is saying that -2+2.0 is 4.x, where x is a huge decimal involving
> E-16 (in other words, a really tiny number). Does anyone have any idea
> what is going on here?
Let's reword the description of the problem...
"2.0 - 2 is a really tiny number close to 4e-16"
Welcome to the wonders of floating point maths! Repeat after me:
Floats are not real numbers... floats are not real numbers...
floats are not real numbers... everything you learned about
arithmetic in school only *approximately* applies to floats.
Half :) and half :(
First off, anything involving e-16 isn't a "huge decimal", it's a tiny
decimal, very close to zero, no matter what the x is:
0.0000000000000004x
Also, although you say "-2 + 2.0" in a comment, that's not actually what
you calculate. I know this even though I don't know what you calculate,
because I can test -2 + 2.0 and see that it is exactly zero:
>>> -2 + 2.0 == 0
True
Somewhere in your calculation you're probably calculating something
which *looks* like 2.0 but isn't. Here's an example:
>>> x = 2 + 1e-14
>>> print(x)
2.0
>>> x == 2.0
False
but you can see the difference by printing the float with more decimal
places than shown by the default view:
>>> repr(x)
'2.00000000000001'
Another problem: you calculate your values by repeated addition. This is
the wrong way to do it, because each addition has a tiny little error,
and repeating them just compounds error upon error. Here's an example:
>>> x = 0.0
>>> for i in range(10):
... x += 0.1
...
>>> x == 1.0
False
>>> print(x)
1.0
>>> repr(x)
'0.99999999999999989'
The right way is to do it like this:
>>> x = 0.0
>>> for i in range(1, 11):
... x = i*0.1
...
>>> x == 1.0
True
This ensures that errors don't compound.
Some further resources:
http://floating-point-gui.de/
http://introcs.cs.princeton.edu/91float/
David Goldberg used to have a fantastic (although quite technical)
discussion of floating point issues, "What Every Computer Scientist
Should Know About Floating-Point Arithmetic":
http://docs.sun.com/source/806-3568/ncg_goldberg.html
Unfortunately, since Oracle bought Sun, they've removed the article.
Bastards.
If you can find a copy of Apple's old "Apple Numeric Manual" (2nd
Edition), it has a fantastic introduction by William Kahan. Even though
the book is about Apple's SANE, a lot will apply to other floating point
systems as well.
Google on William Kahan and read his stuff :)
--
Steven
More information about the Tutor
mailing list