我有一个从函数返回的两个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&lt; 1”语句。
我尝试过设置
np.set_printoptions(precision=10)
期望看到变量之间的差异,但即便如此,它们在打印时都显示为1.0。
此时我有点困惑。 有没有办法可视化这些float64数字的差异? 是否可以“if / then”可靠地用于检查float64号码?
由于 特雷瓦雷兹
答案 0 :(得分:4)
打印值不正确。在您使用y
时,使用1
时float64
小于1
,使用float32
时大于或等于float
。这是预期的,因为舍入误差取决于epsilon
的大小。
为了避免这种问题,在处理浮点数时,你应该总是决定一个“最小错误”,通常称为epsilon
,而不是比较相等,检查结果是否最远{ {1}}来自目标值:
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
在评估调用str
时调用了repr
:
In [9]: str(np.float64(1) - 1e-16)
Out[9]: '1.0'
In [10]: repr(np.float64(1) - 1e-16)
Out[10]: '0.99999999999999989'
答案 1 :(得分:1)
In [26]: x = numpy.float64("1.000000000000001")
In [27]: print x, repr(x)
1.0 1.0000000000000011
换句话说,你被print
陈述中的精度损失所困扰。该值与1
略有不同。
答案 2 :(得分: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.
希望它帮助了其他人,因为它帮助了我。