$ python --version
Python 2.7.15
$ type test.py
import random
while True:
a = random.uniform(0, 1)
b = a ** 2
c = a * a
if b != c:
print "a = {}".format(a)
print "a ** 2 = {}".format(b)
print "a * a = {}".format(c)
break
$ python test.py
a = 0.145376687586
a ** 2 = 0.0211343812936
a * a = 0.0211343812936
Я смог воспроизвести это только в Windows-сборке Python - точнее: Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
. На моей установке в Arch Linux Python (Python 2.7.15 (default, May 1 2018, 20:16:04) [GCC 7.3.1 20180406] on linux2
) цикл, кажется, не заканчивается, указывая, что a**2 = a * a
инвариант.
Что здесь происходит? Я знаю, что поплавки IEEE приходят с множеством заблуждений и особенностей (это, например, не отвечает на мой вопрос), но я не вижу, какая часть спецификации или какая реализация **
могла бы это позволить.
Чтобы адресовать дублирующее пометку: скорее всего, это не проблема математической задачи с плавающей запятой IEEE и проблема с реализацией оператора **
. Следовательно, это не дубликат вопросов, которые задают только вопросы с плавающей точкой, такие как точность или ассоциативность.