以下代码导致执行print语句:
import numpy as np
import math
foo = np.array([1/math.sqrt(2), 1/math.sqrt(2)], dtype=np.complex_)
total = complex(0, 0)
one = complex(1, 0)
for f in foo:
total = total + pow(np.abs(f), 2)
if(total != one):
print str(total) + " vs " + str(one)
print "NOT EQUAL"
但是,我输入[1/math.sqrt(2), 1/math.sqrt(2)]
会导致total
为one
:
(1+0j) vs (1+0j) NOT EQUAL
将NumPy与Python的复杂类型混合起来是否有用?
答案 0 :(得分:3)
使用浮点数时,请务必记住,使用这些数字永远不准确,因此计算每次都会受到舍入误差的影响。这是由floating point arithmetic 的设计引起的,目前是在资源有限的计算机上进行高任意精度数学的最实用的方法。你无法精确计算使用浮点数(意味着你几乎没有替代方案),因为你的数字必须在某个地方被切断以适应合理的内存量(在大多数情况下最多为64位),这个截止值通过四舍五入来完成(见下面的例子)。
为了正确处理这些缺点,你永远不应该将浮标视为平等,而是为了接近。 Numpy提供了两个函数:np.isclose
用于比较单个值(或数组的逐项比较)和整个数组的np.allclose
。后者是np.all(np.isclose(a, b))
,因此您可以获得数组的单个值。
>>> np.isclose(np.float32('1.000001'), np.float32('0.999999'))
True
但有时候舍入是非常切实可行的,符合我们analytical的预期,例如:
>>> np.float(1) == np.square(np.sqrt(1))
True
在平方后,该值将减小以适应给定的内存,因此在这种情况下,它将四舍五入到我们期望的值。
这两个函数具有内置的绝对和相对容差(您也可以将其作为参数给出),用于比较两个值。默认情况下,它们是rtol=1e-05
和atol=1e-08
。
另外,不要将不同的包与其类型混合。如果使用Numpy,请使用Numpy-Types和Numpy-Functions。这也会减少您的舍入误差。
顺便说一句:在处理广泛的指数差异的数字时,舍入错误会产生更大的影响。
答案 1 :(得分:2)
我想,与实数相同的考虑是适用的:永远不要假设它们可以相等,但相当接近:
eps = 0.000001
if abs(a - b) < eps:
print "Equal"