Am 11.03.2011 06:05, schrieb Steven D'Aprano:
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 :)



Damn, you're fast!! ;-))
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to