Smatik
Smatik

Reputation: 407

A confusion in Python's If else logic

I am learning python this summer online from MITx: 6.00.1x. Here's the code

x = 23.0
epsilon = 0.01
step = 0.1
guess = 0.0

while abs(guess**2-x) >= epsilon:
    if guess <= x:
        guess += step
    else:
        break

if abs(guess**2 - x) >= epsilon:
    print "outside"
    print guess
else:
    print 'succeeded: ' + str(guess)

According to me, the while loop should break when the value of guess becomes 23.1 . because when guess=23,the if condition, guess<=23, will satisfy and the next line guess+=step should execute which will make guess=23.1 and then in the next iteration, guess<=23.0 will not be satisfied and the loop will break. But when I run the code the output comes out to be

outside

23.0

shouldn't it be 23.1 ?

Upvotes: 1

Views: 138

Answers (2)

tegancp
tegancp

Reputation: 1202

Your understanding of the logic here seems sound; the issue is in fact with the way that python stores internally (and hence adds and compares) floating point numbers.

Here's a modified version of your code that should let you see what's going on:

x = 2
epsilon = 0.01
step = 0.1
guess = 0.0
while abs(guess**2-x) >= epsilon:
    print format(guess, '.20'), guess <= x
    if guess <= x:
        guess += step
    else:
        break

if abs(guess**2 - x) >= epsilon:
    print "outside"
    print guess
else:
    print 'succeeded: ' + str(guess)

This will give you the result:

0.0 True
0.10000000000000000555 True
0.2000000000000000111 True
0.30000000000000004441 True
0.4000000000000000222 True
0.5 True
0.5999999999999999778 True
0.69999999999999995559 True
0.79999999999999993339 True
0.89999999999999991118 True
0.99999999999999988898 True
1.0999999999999998668 True
1.1999999999999999556 True
1.3000000000000000444 True
1.4000000000000001332 True
1.500000000000000222 True
1.6000000000000003109 True
1.7000000000000003997 True
1.8000000000000004885 True
1.9000000000000005773 True
2.0000000000000004441 False
outside
2.0

Here we see the value of guess at each step, displayed to 20 decimal places, and the value that python is getting when it does the comparison guess <= x. So the actual value of step is very, very close to (but not exactly equal to) the number 0.1.

The moral here: be very careful when comparing floating point numbers.

Upvotes: 1

Yu Hao
Yu Hao

Reputation: 122373

Because floating point numbers like 0.1 can't be represented precisely using float type. So the floating point number arithmetic is not precise, either. For example:

>>> 0.1 * 3
0.30000000000000004

In your cose, before guess reaches 23.0, you would assume it being 22.9, but it's actually a number very close to 22.9, in this case, probably a little bit smaller.

Upvotes: 2

Related Questions