# [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'

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

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.