[Tutor] very odd math problem

Knacktus knacktus at googlemail.com
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).

To elaborate, you could add some lines to your code:

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



More information about the Tutor mailing list