Исчерпывающая точность с плавающей точкой в ​​(казалось бы) бесконечном цикле

У меня есть следующий скрипт Python:

x = 300000000.0
while (x < x + x):
    x = x + x
    print "exec: " + str(x)
print "terminated" + str(x)

Этот, казалось бы, бесконечный цикл завершается довольно быстро, если x является числом с плавающей запятой. Но если я вместо этого изменю x на 300000000, он попадет в бесконечный цикл (в моем тесте длится дольше минуты).

Я думаю, что это связано с тем, что он исчерпывает точность числа с плавающей запятой, которое может быть представлено в памяти. Может кто-нибудь дать более подробное объяснение, почему это так?

3 ответа

Решение
  • Когда вы инициализируете x в 300000000целая математика используется во всей программе.
  • Когда вы инициализируете x в 300000000.0вместо этого используется математика с плавающей точкой.

В Python целые числа могут расти как угодно большие. (Точнее, они ограничены доступной памятью.) Это означает, что целочисленная версия вашей программы требует очень много времени для завершения.

Самый большой float около 1.8e308, Требуется около 1000 итераций версии цикла с плавающей запятой, чтобы превысить это значение, и в этот момент x получает положительную бесконечность, и программа завершается.

Это потому, что происходит переполнение с плавающей точкой. В этом случае, согласно IEEE754, x примет значение положительной бесконечности, которая по определению не меньше чем что-либо еще:

>>> x = float("inf")
>>> x
inf
>>> x + x
inf
>>> x < x + x
False

x удваивается после каждого шага. Конечное число x никогда не бывает равным 2 * x, Но как только вы превысите максимальный показатель вашего типа с плавающей запятой, удваивается x в +infinity, А также +infinity = 2*+infinity, Таким образом, цикл заканчивается в этой точке.

Другие вопросы по тегам