Reputation: 9
I am having a bit of trouble understanding some results I am getting while operating with Python 2.7.
>>> x=1
>>> e=1e-20
>>> x+e
1.0
>>> x+e-x
0.0
>>> e+x-x
0.0
>>> x-x+e
1e-20
This is copied directly from Python. I am having a class on how to program on Python and I do not understand the disparity of results (x+e==1, x-x+e==1e-20 but x+e-x==0 and e+x-x==0).
I have already read the Python tutorial on Representation Errors, but I believe none of that was mentioned there
Thanks in advance
Upvotes: 1
Views: 182
Reputation: 11113
This is because of the way that computers represent floating point numbers.
This is all really in binary format but let's pretend that it works with base 10 numbers because that's a lot easier for us to relate to.
A floating point number is expressed on the form 0.x*10^y
where x is a 10-digit number (I'm omitting trailing zeroes here) and y is the exponent. This means that the number 1.0 is expressed as 0.1*10^1
and the number 0.1 as 0.1*10^0
.
To add these two numbers together we need to make sure that they have the same exponent. We can do this easily by shifting the numbers back and forth, i.e. we change 0.1*10^0
to 0.01*10^1
and then we add the together to get 0.11*10^1
.
When we have 0.1*10^1
and 0.1*10^-19
(1e-20) we will shift 0.1*10^-19
20 steps, meaning that the 1 will fall outside the range of our 10 digit number so we will end up with 0.1*10^1 + 0.0*10^1 = 0.1*10^1
.
The reason you end up with 1e-20 in your last example is because addition is done from left to right, so we subtract 0.1*10^1
from 0.1*10^1
ending up with 0.0*10^0
and add 0.1*10^-19
to that, which is a special case where we don't need to shift any of them because one of them is exactly zero.
Upvotes: 2
Reputation: 280564
Floating-point addition is not associative.
x+e-x
is grouped as (x+e)-x
. It adds x
and e
, rounds the result to the nearest representable number (which is 1), then subtracts x
from the result and rounds again, producing 0.
x-x+e
is grouped as (x-x)+e
. It subtracts x
from x
, producing 0, and rounds it to the nearest representable number, which is 0. It then adds e
to 0, producing e
, and rounds it to the nearest representable number, which is e
.
Upvotes: 4