$ 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
我只能在 Python 的 Windows 构建版本上复现这个问题 - 确切地说:Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
。在我安装了 Python 的 Arch Linux 上(Python 2.7.15 (default, May 1 2018, 20:16:04) [GCC 7.3.1 20180406] on linux2
),这个循环似乎没有终止,这表明 a**2 = a * a
不变式在那里成立。
这里发生了什么?我知道 IEEE 浮点数有许多误解和特异性(例如,这个并不能回答我的问题),但我不明白规范的哪个部分或者什么样的 **
实现可以允许这种情况。
针对重复标记的问题:这很可能不是直接的 IEEE 浮点运算问题,更多的是关于 **
运算符实现的问题。因此,这不是与浮点问题(如精度或结合性)相关的重复问题。
repr
显示更多位数,这样我们就可以看到它失败的确切值以及如何失败。 - user2357112a ** 2
没有被实现为a * a
。 - Oliver Charleswortha**2 == a*a
只会带来痛苦。 - user2357112a**2 == a*a
的恒等性。因此,如果在某些实现中它不能成立,则有其他原因导致,而非浮点数的性质。我并没有建议 OP 或任何人依赖于这个恒等式。我只是陈述了失败的原因不是由于浮点运算的性质。 - Eric Postpischil