我对numpy.arange
生成的对象有最奇怪的行为:
for i in numpy.arange(xo, xn+h, h):
xs.append(float(i))
在这种情况下,xo=1
,xn=4
,h=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)
发出同样的事情(这是我实际需要工作的部分)。
答案 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。