Python 为什么单精度和双精度比较在numpy中失败?
鉴于: 我不明白为什么Python 为什么单精度和双精度比较在numpy中失败?,python,numpy,floating-point,Python,Numpy,Floating Point,鉴于: 我不明白为什么a==b是假的,但是np.allclose(a,b)是真的。毕竟,单精度浮点数的范围是~10^38。事实上,既然np.can_cast(1e20,'f4')是真的,我希望上面的等式应该是有效的 我想这可能与浮点数表示法的奇怪之处有关,但我不完全理解内部到底发生了什么。原因确实是二进制浮点数表示法: val = 1e20 a = np.array(val); b = np.array(val, 'f4') 原因是在64位中,a是: In [41]: print('{}'.f
a==b
是假的,但是np.allclose(a,b)
是真的。毕竟,单精度浮点数的范围是~10^38。事实上,既然np.can_cast(1e20,'f4')
是真的,我希望上面的等式应该是有效的
我想这可能与浮点数表示法的奇怪之处有关,但我不完全理解内部到底发生了什么。原因确实是二进制浮点数表示法:
val = 1e20
a = np.array(val); b = np.array(val, 'f4')
原因是在64位中,a是:
In [41]: print('{}'.format(a))
1e+20
In [42]: print('{}'.format(b))
1.00000002004e+20
符号位为0,然后是11位指数100 0100 0001,其余为尾数。将其转换为32位并返回以进行比较,将尾数的最后一位剥离:
0100 0100 0001 0101 1010 1111 0001 1101 0111 1000 1011 0101 1000 1100 01000000
因此,当==运算符检查确切的二进制等价性时,比较浮点可能会产生误导。根据您的意图,您可以考虑检查协议的级别,例如:
0100 0100 0001 0101 1010 1111 0001 1101 1000 0000 0000 0000 0000 0000 00000000
如果晶圆厂(a-b)<1E-6:
打印(“相等”)
否,在比较浮点值时,不应总是与公差进行比较。在有限的情况下,它是合适的,如果引入误报,它只会以牺牲误报为代价来减少误报。因此,在没有正确理解权衡的情况下,决不能这样做。这是一个糟糕的建议。用数学表示法(符号、有效位和二的幂)来解释浮点运算的效果比用表示它们的位更好。位是不相关的,转换时位不会被“剥离”;有效位是四舍五入的。我同意这个建议可能有误导性,我在编辑中对此进行了更正。
if fabs(a-b) < 1E-6:
print('equal')