2

谷歌搜索了一段时间后,我在这里发帖寻求帮助。

我有两个从函数返回的 float64 变量。他们两个显然都是1:

>>> x, y = somefunc()
>>> print x,y
>>> if x < 1 :   print "x < 1"
>>> if y < 1 :   print "y < 1"
1.0  1.0
y < 1

当变量定义为 float32 时,行为会发生变化,在这种情况下,不会出现 'y<1' 语句。

我试过设置

np.set_printoptions(precision=10)

期望看到变量之间的差异,但即便如此,它们在打印时都显示为 1.0。

在这一点上我有点困惑。有没有办法可视化这些 float64 数字的差异?是否可以可靠地使用“if/then”来检查 float64 数字?

谢谢特雷瓦雷斯

4

3 回答 3

4

打印的值不正确。在您的情况下,使用时y小于使用时1,使用时float64大于或等于. 这是意料之中的,因为舍入误差取决于.1float32float

为避免此类问题,在处理浮点数时,您应该始终确定“最小误差”,通常称为“最小误差”,而不是比较是否相等,而是检查结果是否与目标值epsilon最远:epsilon

In [13]: epsilon = 1e-11

In [14]: number = np.float64(1) - 1e-16

In [15]: target = 1

In [16]: abs(number - target) < epsilon   # instead of number == target
Out[16]: True

特别是,numpy已经提供了np.allclose在给定一定容差的情况下比较数组是否相等的有用的方法。即使参数不是数组(例如np.allclose(1 - 1e-16, 1) -> True),它也可以工作。

但是请注意,numpy.set_printoptions这不会影响np.float32/64的打印方式。它只影响数组的打印方式:

In [1]: import numpy as np

In [2]: np.float(1) - 1e-16
Out[2]: 0.9999999999999999

In [3]: np.array([1 - 1e-16])
Out[3]: array([ 1.])

In [4]: np.set_printoptions(precision=16)

In [5]: np.array([1 - 1e-16])
Out[5]: array([ 0.9999999999999999])

In [6]: np.float(1) - 1e-16
Out[6]: 0.9999999999999999

另请注意,在交互式解释器中执行print y或评估会产生不同的结果:y

In [1]: import numpy as np

In [2]: np.float(1) - 1e-16
Out[2]: 0.9999999999999999

In [3]: print(np.float64(1) - 1e-16)
1.0

不同之处在于在评估调用时print调用:strrepr

In [9]: str(np.float64(1) - 1e-16)
Out[9]: '1.0'

In [10]: repr(np.float64(1) - 1e-16)
Out[10]: '0.99999999999999989'
于 2013-08-19T11:14:54.690 回答
1
In [26]: x  = numpy.float64("1.000000000000001")

In [27]: print x, repr(x)
1.0 1.0000000000000011

换句话说,你被print陈述的准确性损失所困扰。该值与 略有不同1

于 2013-08-19T10:06:25.977 回答
0

按照此处提供的建议,我以这种方式总结了答案:

为了在浮点数之间进行比较,程序员必须为它们定义一个最小距离(eps)才能被认为是不同的(例如,eps=1e-12)。这样做,条件应该这样写:

Instead of (x>a), use (x-a)>eps
Instead of (x<a), use (a-x)>eps
Instead of (x==a), use abs(x-a)<eps

这不适用于整数之间的比较,因为它们之间的差固定为 1。

希望它能帮助别人,因为它帮助了我。

于 2013-08-20T08:49:06.290 回答