Reputation: 101
x = 25
epsilon = 0.01
step = 0.1
guess = 0.0
while guess <= x:
if abs(guess**2 -x) >= epsilon:
guess += step
if abs(guess**2 - x) >= epsilon:
print('failed')
else:
print('succeeded: ' + str(guess))
I am given this Python program which attempts to calculate the square root of a number x
. For some reason, this program loops indefinitely and I'm not sure why.
There are only finitely many values of guess
, because, after guess>x
(i.e. when guess>=25.1
,, the while
loop then stops). The while
command in the middle of the program is the only thing that loops, so what is happening?
Upvotes: 0
Views: 225
Reputation: 1121486
You only increment guess
when the condition abs(guess**2 -x) >= epsilon
is true. That condition is false when guess = 5.0
. At that point guess
never changes anymore but guess <= x
is still true and you enter an infinite loop:
>>> x = 25
>>> epsilon = 0.01
>>> guess = 5.0
>>> abs(guess**2 - x)
0.0
>>> abs(guess**2 - x) >= epsilon
False
Starting at guess = 0.0
and incrementing by 0.1
means that your loop executes 50 times before reaching that point, after which guess
never changes again.
In reality, guess
is not 5.0
exactly because adding an approximation of 0.1
(which can't be represented exactly using binary fractions), gives you a value a small amount lower:
>>> guess = 0.0
>>> for _ in range(50):
... guess += 0.1
...
>>> guess
4.999999999999998
but that difference is still smaller than epsilon
.
You probably want to break the while
loop when you have reached within epsilon
distance of the target:
while guess <= x:
if abs(guess**2 -x) < epsilon:
break
guess += step
Upvotes: 2
Reputation: 350137
Even if you change the while condition to <
instead of <=
, it will still loop indefinitely, because of floating point inaccuracy.
Although you add steps of 0.1, the guess
value will not become exactly 5, but 4.999999999999998, at which point the loop will continue to run without entering in the if
block.
This is at least what I see happening here
Upvotes: 0