[Tutor] very odd math problem

Fri Mar 11 06:57:45 CET 2011

```Am 11.03.2011 04:23, schrieb Alex Hall:
> 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?

You can find some great posts at a thread about decimal floating point
numbers some weeks ago for background reading. Or (and) look at this:

http://docs.python.org/tutorial/floatingpoint.html#floating-point-arithmetic-issues-and-limitations

Now my guess is:

i is calculated as a sum of floats of step 0.1. That means you have in
the base 2 representation an approximation of 0.1, not "exactly" 0.1,
but something like 0.10000000000000123123. When i reaches approximately
2.0, it is actually 2.00000000000000000342374 (or what ever). On the
other hand, e1 can be represented precisely if it's 2.0 in the base 2
representation. But the sum of e1 and i is actually your tiny number.
That's why 2.0 - 2.0 is exactly 0.0, but (20*0.1 - 2.0 is not).

def getCoords(f, e1, e2, step=.1):
time=0
i=0
coords=[]
while time<=e2:
print "time="+str(e1)+"+"+str(i)+"="
print type(e1)
print type(i)
time=e1+i
time_2 = e1 + e2
print "%s, %.24f" % (time, time) # app 0.0
print "%s, %.24f" % (time_2, time_2) # exact 0.0
coords.append((time, evaluate(f, time)))
i=i+1*step
return coords

The reason why Python prints i as 2.0 in the first print statement is
probably due to some internal auto-rounding when using str(). See the
last paragraph of the link above. No idea, what's exactly going on under
the hood.

HTH,

Jan

>
> def getCoords(f, e1, e2, step=.1):
>   #returns a list of (x,y) tuples from e1 to e2 at the given accuracy (step)
>   time=0
>   i=0
>   coords=[]
>   while time<=e2:
>    print "time="+str(e1)+"+"+str(i)+"="
>    time=e1+i
>    print time #watch this line when above is -2+2.0
>    coords.append((time, evaluate(f, time)))
>    i=i+1*step
>   return coords
>
> def evaluate(x,y): return x*y

```