Python float32/float64 numpy变量的不同行为

Python float32/float64 numpy变量的不同行为,python,numpy,Python,Numpy,谷歌搜索了一段时间后,我在这里发帖寻求帮助 我有两个从函数返回的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 希望看到变量之间的差异,但即使如此,它们在打印时都显示为1.0

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

我有两个从函数返回的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
希望看到变量之间的差异,但即使如此,它们在打印时都显示为1.0

在这一点上我有点困惑。 有没有办法把这些数字的差别形象化? 是否可以可靠地使用“if/then”检查浮点数

谢谢 特雷瓦雷斯

In [26]: x  = numpy.float64("1.000000000000001")

In [27]: print x, repr(x)
1.0 1.0000000000000011
换句话说,在
print
语句中,您会受到精度损失的困扰。该值与
1

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

为避免此类问题,在处理浮点数时,应始终确定一个“最小误差”,通常称为
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
还请注意,在交互式解释器中执行
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
调用
str

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

In [10]: repr(np.float64(1) - 1e-16)
Out[10]: '0.99999999999999989'

根据这里提供的建议,我以这种方式总结了答案:

为了在浮点数之间进行比较,程序员必须定义一个最小距离(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
使用(x-a)>eps代替(x>a)
而不是(xeps

使用abs(x-a)代替(x==a)我不理解你的问题。显然错误在打印的表示法中,
y
float64
情况下小于1,并且相等(或更大)由于舍入错误,在使用
float32
时设置为
1
。在处理浮点值时,您永远不能使用相等的比较。修复最小错误(例如
epsilon=1e-16
或更小/更大,取决于应用程序),如果abs(数字-1),则执行
@Bakuriu您可以将此作为一个答案发布…您已经解释了正在发生的事情,
print
输出11个有效数字,float64有15个左右。谢谢您Bakuriu,这是一个非常全面的答案,澄清了我的疑问。我只是想知道是什么Numpy提供函数作为“Numpy.where”的要点,没有关于浮点数的这些细微之处的警告?从文档中可以看出,它可以直接用于浮点数,而不考虑精度问题:>>>x=np.arange(9.)。重塑(3,3)>>x[np.where(x>3.0)]数组([4,5,6,7,8])@Trevarez这不是numpy的问题。这是任何浮点计算的问题。这是你应该知道的(参见示例)。如果你想检查哪些值大于
3.0
,达到一定精度,你可以先减去ε(即
x[np.where((x-epsilon)>3.0)]
)。很棒的文章。我想我终于理解了“问题”的范围。再次感谢您的解释。注意:您应该使用
np.allclose(value,other_value)
。不要定义您自己的任意ε值。
In [9]: str(np.float64(1) - 1e-16)
Out[9]: '1.0'

In [10]: repr(np.float64(1) - 1e-16)
Out[10]: '0.99999999999999989'
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