2016-11-06 3 views
0
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)) 

Мне дана эта программа Python, которая пытается вычислить квадратный корень из числа x. По какой-то причине эта программа работает бесконечно, и я не уверен, почему.Почему эта программа Python работает бесконечно?

Есть только конечное число значений guess, потому что, после того, как guess>x (то есть, когда guess>=25.1 ,, цикл while затем останавливается). Команда while в середине программы - это единственное, что происходит в цикле, так что происходит?

+0

Помещенный некоторые операторы печати и узнай – scrappedcola

+0

Так что же происходит, когда 'догадка = 5.0'? Ваш оператор 'if' не будет соответствовать, но' guess <= x' по-прежнему истинно. –

+0

Вы не останавливаете цикл, если догадка находится в пределах epsilon. – BrenBarn

ответ

2

Вы только увеличиваете guess, когда условие abs(guess**2 -x) >= epsilon является правдой. Это условие false когда guess = 5.0. В этот момент guess никогда не меняется больше, но guess <= x по-прежнему верно, и вы войти в бесконечный цикл:

>>> x = 25 
>>> epsilon = 0.01 
>>> guess = 5.0 
>>> abs(guess**2 - x) 
0.0 
>>> abs(guess**2 - x) >= epsilon 
False 

Начало в guess = 0.0 и увеличивающиеся на 0.1 означает, что ваш цикл выполняется 50 раз до достижения этой точки, после чего guess никогда не меняется еще раз.

В действительности, guess не 5.0 именно потому, что добавление приближение 0.1 (которое не может быть представлено именно с использованием двоичных дробей), дает значение небольшое количество меньше:

>>> guess = 0.0 
>>> for _ in range(50): 
...  guess += 0.1 
... 
>>> guess 
4.999999999999998 

, но это различие все еще меньше, чем epsilon.

Вы, вероятно, хотите перерывwhile петли, когда вы достигли в epsilon расстоянии от цели:

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

Даже если изменить условия пока к < вместо <=, он все равно будет цикл до бесконечности , из-за неточности с плавающей запятой.

Хотя вы добавляете шаги 0,1, значение guess не станет ровно 5, но 4.999999999999998, после чего цикл продолжит работу без ввода в блок if.

Это, по крайней мере то, что я вижу, что происходит here

+0

Шаг составляет 0,1, а не 0,01. 50 * 0,1 все равно 5.0 точно ('(50 * 0,1) .is_integer()' истинно). –

+0

Возможно, это зависит от процессора, потому что я вижу, что это происходит [здесь] (https://repl.it/Dz1g/6). – trincot

+0

Нет, я могу воспроизвести его, когда я отступаю от умножения и добавляю 50 раз. –

Смежные вопросы