Как уже упоминалось в моем исходном комментарии и во всех ответах, квадратный корень из 2 равен иррациональным . Квадратный корень каждого целого числа, которое не является идеальным квадратом, иррационально в этом отношении, поэтому 2 не является особенным в этом отношении. Важно то, что x**2 == 2
никогда не будет истинным для любых x
конечной точности (поскольку конечная точность - это еще один способ сказать, что число рационально).
Другие ответы предлагают поиск, пока вы не достигнете некоторой фиксированной, заранее определенной точности. Это хорошо работает, особенно если вы заранее знаете двоичный порядок величины ответа, с тех пор вы можете установить точность результата в последней цифре.
Я бы хотел предложить более естественный подход. Вы можете проверить, точно ли значение вашего центра равно одной из границ. Это будет означать, что половина вашей разницы представляет менее одной цифры точности в вашем текущем предположении. Ваша формулировка центра уже правильна: i = low + (high - low) / 2
можно сравнить с low
и high
, используя ==
, а i = (low + high) / 2
- нет. Это связано с тем, что точность high - low
больше или равна точности любой границы, тогда как low + high
может потерять некоторые цифры.
Итак, вот что я бы порекомендовал:
num = 2
low = 1
high = num
guess = low + (high - low) / 2
count = 0
while guess != low and guess != high:
sqr = guess * guess
if sqr == num:
break
elif(sqr < num):
low = guess
else:
high = guess
guess = low + (high - low) / 2
count += 1
else:
if abs(low * low - num) < abs(high * high - num):
guess = low
else:
guess = high
print(count, ':', sqr)
print(num ** (.5), '~=', guess)
Я добавил count
для проверки. Результат получается за 52 итерации с точностью до 1 знака точности:
52 : 2.0000000000000004
1.4142135623730951 ~= 1.4142135623730951
Окончательная проверка по границам (предложение else
в while
) гарантирует, что вы получите самый близкий результат к желаемому результату, независимо от того, какой вы нажали первым.
Сходимость нормальна: 64-битное число с плавающей точкой в формате IEEE-754 имеет 53 бита в мантиссе, поэтому имеет смысл, что вам придется вдвое сократить пространство поиска ровно столько раз чтобы получить результат (первый раз за пределами цикла).
Вот фрагмент, который я использовал для тестирования: https://ideone.com/FU9r82