在python中,检查两个复数是否相同的更好方法是什么?

在python中,检查两个复数是否相同的更好方法是什么?,python,python-2.7,numpy,Python,Python 2.7,Numpy,在python 2.7.3中测试mpi4py的comm.reduce()和comm.reduce()方法时,我遇到了以下行为: 有时,将两个在屏幕上打印时看起来相同的复数(输入'numpy.complex128',这是一些并行计算的输出)相减会产生非零结果 将它们与==进行比较偶尔会产生False 例如: print z1, z2, z1-z2 (0.268870295763-0.268490433604j) (0.268870295763-0.268490433604j) 0j print

在python 2.7.3中测试mpi4py的
comm.reduce()
comm.reduce()
方法时,我遇到了以下行为:

  • 有时,将两个在屏幕上打印时看起来相同的复数(输入'numpy.complex128',这是一些并行计算的输出)相减会产生非零结果

  • 将它们与
    ==
    进行比较偶尔会产生
    False

例如:

print z1, z2, z1-z2
(0.268870295763-0.268490433604j) (0.268870295763-0.268490433604j) 0j
print z1 == z2
True
但是

print z1, z2, z1-z2
(0.226804302192-0.242683516175j) (0.226804302192-0.242683516175j) (-2.77555756156e-17+5.55111512313e-17j)
print z1 == z2
False
我认为这与浮点数的有限精度有关,所以我求助于只检查差值
abs(z1-z2)
是否大于1e-16(从来没有过-如果
reduce()
reduce()
相等,这是人们所期望的)。(编辑:这实际上不是检查平等性的好方法。请参见此处:)

我想知道是否有一种更直接的方法来比较python中的复数

还有,为什么会出现这种行为?毕竟,一个浮点(据我所知,一个复数基本上是两个浮点的元组)以二进制形式存储在机器上,作为一个位序列。如果两个数字用相同的二进制序列表示,那么差应该是零,与
==
比较应该得到
true
,这难道不是真的吗

编辑:好的,我找到了这个,基本上可以归结为同一件事


但问题的最后一部分仍然存在:如果在二进制中,浮点基本上都是由整数表示的,那么为什么它们会这样工作?

float
以产生相同逻辑结果的方式派生的值在二进制中并不总是具有相同的表示形式,因为
float
不是无限精度,它的代表性也有局限性。不同顺序的相同逻辑等效步骤有时会出现精度错误,导致结果略有不同

通常,当您知道值很小或范围很窄时,检查与
float
s的“关闭”相等性的方法是执行以下操作:

if abs(a - b) < 1e-9:  # Substitute your own threshold for equality

等效代码基于相对公差进行缩放,因此如果您的值可以跨越整个
复杂类型的范围,您将希望使用类似的值(其中
rel\u tol
abs\u tol
由您根据您的问题集选择).

仅仅因为它们非常接近,在12位小数点处看起来相同,并不意味着它们是相同的数字。你不是在看“位序列”;“只有小数点的近似值。”@khelwood,说得好。我刚才也意识到了。请参见编辑。关于浮点问题有一个非常好的讨论。我认为使用像abs(a-b)<1e-9这样的东西是非常危险的。想象一下减去3.9e-100和2.7e-100。他们是完全不同的,但根据上述情况,他们将被视为平等的。你建议的第二种方法更好。@The.real.gruycho:同意。它与空间有关;如果你知道这些数字很小,那么绝对阈值就可以了,但是如果这些数字可能在可表示范围内的任何地方,你就需要一个相对阈值。我已经更新了答案,使之更加清晰。
 abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)