将numpy.float64转换为float时的奇怪行为

时间:2013-10-22 07:20:15

标签: python numpy casting floating-point sympy

我对numpy.arange生成的对象有最奇怪的行为:

for i in numpy.arange(xo, xn+h, h):
    xs.append(float(i))

在这种情况下,xo=1xn=4h=0.1

现在,我希望xs[-1]完全等于4.0 == float(4)。但是,我得到以下内容:

>>> foo = xs[-1]
>>> foo == float(4)
False
>>> float(foo) == float(4)
False
>>> foo
4.0
>>> type(foo)
<type 'float'>
>>> int(sympy.ceiling(4.0)), int(sympy.ceiling(foo))
4 5

这里到底发生了什么?

print type(i)循环中放置for会打印<type 'numpy.float64'>。也许在float(i)施法期间会发生什么?使用numpy.asscalar不会改变任何内容。

使用math.ceil(foo)代替sympy.ceiling(foo)发出同样的事情(这是我实际需要工作的部分)。

2 个答案:

答案 0 :(得分:2)

In [10]: for i in numpy.arange(xo, xn+h, h):
        xs.append(float(i))
....:     

In [11]: xs
Out[11]: 
[1.0,
1.1,
1.2000000000000002,
1.3000000000000003,
1.4000000000000004,
1.5000000000000004,
1.6000000000000005,
1.7000000000000006,
1.8000000000000007,
1.9000000000000008,
2.000000000000001,
2.100000000000001,
2.200000000000001,
2.300000000000001,
2.4000000000000012,
2.5000000000000013,
2.6000000000000014,
2.7000000000000015,
2.8000000000000016,
2.9000000000000017,
3.0000000000000018,
3.100000000000002,
3.200000000000002,
3.300000000000002,
3.400000000000002,
3.500000000000002,
3.6000000000000023,
3.7000000000000024,
3.8000000000000025,
3.9000000000000026,
4.000000000000003]

这就是为什么你没有得到想要的结果,由于浮点精度,它不能给你的测试真实。这也解释了为什么如果你做一个像天花板这样的圆形操作,你会得到五个而不是四个。

编辑: 检查x和y是否相同(在某个误差范围内),您可以执行以下操作,但我认为(已应该)已经在python中可以为您执行此操作的内容

def isnear(x,y, precision = 1e-5):
    return abs(x-y)<precision

EDIT2: 或者作为ali_m说:

numpy.allclose(x, y, atol = 1e-5)

答案 1 :(得分:1)

这并不奇怪 - 它只是浮点运算的工作方式,因为它无法准确表示大多数值。如果你以浮点重复计算(arange()这里加0.1到1然后再加上0.1到另外29次)如果你正在处理的数字在浮点数上不能完全表示,你就赢了在计算结束时得到一个确切的答案。有关此内容的最佳文章是What Every Computer Scientist Should Know About Floating-Point Arithmetic