Floating point multiplication in python

Thomas Rachel nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de
Tue Sep 6 12:14:57 CEST 2011


Am 06.09.2011 07:57 schrieb xyz:
> hi all:
>
> As we know ,  1.1 * 1.1 is 1.21 .
> But in python ,I got following :
>
>>>> 1.1 * 1.1
> 1.2100000000000002
>
> why python get wrong result? Who can tell me  where's the 0.0000000000000002 from?

1.1 does not fit in a binary floating point number. It is approximated - 
in binary! - as 1.000110011001100110011 ... (periodically).

Note that, while in the decimal system we normally use, only numbers 
which have other components in the denominator than 2 or 5 are 
periodically, in the binary systems only components with 2 are allowed 
in order not to be periodically.

Example: 3.453 is not periodically, because it is 3453/100 and 100 has 
only the factors 2 and 5, each twice.

1/3 = .3333333... is periodically, because it has the factor 3. The same 
applies to 1/6, which has 2 and 3 as factors. The latter destroys the 
non-periodical behaviour.

As said, in the dual system, only the 2 is allowed.

.5 (10) = 2** -1 = .1 (2).
.25 (10) = 2 ** -2 = .01 (2).
.75 (10) = their sum = .11 (2).

But .1 (1/10) is more complicated, -2 would be as well.

As the IEEE floating point representation is limited, there is a slight 
error value which makes the stored value differ from the intended one.

Look here:



>>> x=(1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1)
>>> a=0
>>> for n,i in enumerate(x): a += i*2**-n; print a, a-1.1, i*2**-n, a-olda
...
1 -0.1 1 1
1.0 -0.1 0.0 0.0
1.0 -0.1 0.0 0.0
1.0 -0.1 0.0 0.0
1.0625 -0.0375 0.0625 0.0625
1.09375 -0.00625 0.03125 0.03125
1.09375 -0.00625 0.0 0.0
1.09375 -0.00625 0.0 0.0
1.09765625 -0.00234375 0.00390625 0.00390625
1.099609375 -0.000390625 0.001953125 0.001953125
1.099609375 -0.000390625 0.0 0.0
1.099609375 -0.000390625 0.0 0.0
1.09985351562 -0.000146484375 0.000244140625 0.000244140625
1.09997558594 -2.44140625001e-05 0.0001220703125 0.0001220703125
1.09997558594 -2.44140625001e-05 0.0 0.0
1.09997558594 -2.44140625001e-05 0.0 0.0
1.09999084473 -9.15527343759e-06 1.52587890625e-05 1.52587890625e-05
1.09999847412 -1.52587890634e-06 7.62939453125e-06 7.62939453125e-06
1.09999847412 -1.52587890634e-06 0.0 0.0
1.09999847412 -1.52587890634e-06 0.0 0.0
1.0999994278 -5.72204589933e-07 9.53674316406e-07 9.53674316406e-07
1.09999990463 -9.53674317294e-08 4.76837158203e-07 4.76837158203e-07
1.09999990463 -9.53674317294e-08 0.0 0.0
1.09999990463 -9.53674317294e-08 0.0 0.0
1.09999996424 -3.57627869541e-08 5.96046447754e-08 5.96046447754e-08
1.09999999404 -5.96046456636e-09 2.98023223877e-08 2.98023223877e-08
1.09999999404 -5.96046456636e-09 0.0 0.0
1.09999999404 -5.96046456636e-09 0.0 0.0
1.09999999776 -2.23517426789e-09 3.72529029846e-09 3.72529029846e-09
1.09999999963 -3.72529118664e-10 1.86264514923e-09 1.86264514923e-09
1.09999999963 -3.72529118664e-10 0.0 0.0
1.09999999963 -3.72529118664e-10 0.0 0.0
1.09999999986 -1.3969847501e-10 2.32830643654e-10 2.32830643654e-10
1.09999999998 -2.32831531832e-11 1.16415321827e-10 1.16415321827e-10
1.09999999998 -2.32831531832e-11 0.0 0.0
1.09999999998 -2.32831531832e-11 0.0 0.0
1.09999999999 -8.73123795486e-12 1.45519152284e-11 1.45519152284e-11
1.1 -1.45528034068e-12 7.27595761418e-12 7.27595761418e-12
1.1 -1.45528034068e-12 0.0 0.0
1.1 -1.45528034068e-12 0.0 0.0
1.1 -5.45785638906e-13 9.09494701773e-13 9.09494701773e-13
1.1 -9.10382880193e-14 4.54747350886e-13 4.54747350886e-13
1.1 -9.10382880193e-14 0.0 0.0
1.1 -9.10382880193e-14 0.0 0.0
1.1 -3.41948691585e-14 5.68434188608e-14 5.68434188608e-14
1.1 -5.77315972805e-15 2.84217094304e-14 2.84217094304e-14
1.1 -5.77315972805e-15 0.0 0.0
1.1 -5.77315972805e-15 0.0 0.0
1.1 -2.22044604925e-15 3.5527136788e-15 3.5527136788e-15
1.1 -4.4408920985e-16 1.7763568394e-15 1.7763568394e-15
1.1 -4.4408920985e-16 0.0 0.0
1.1 -4.4408920985e-16 0.0 0.0
1.1 -2.22044604925e-16 2.22044604925e-16 2.22044604925e-16
1.1 0.0 1.11022302463e-16 2.22044604925e-16
1.1 0.0 0.0 0.0
1.1 0.0 0.0 0.0
1.1 0.0 1.38777878078e-17 0.0
1.1 0.0 6.93889390391e-18 0.0

So here we have reached the point where the maximum precision is reached 
- a doesn't change anymore, although it should. The error is about 1E-16.

Now if you multiply two values with an error, the error also propagates 
into the result - PLUs the result can have its own error source - in the 
same order of magnitude.

(a+e) * (a+e) = a*a + 2*a*e + e*e. So your new error term is 2*a*e + e*e 
or (2*a + e) * e.



More information about the Python-list mailing list