简体   繁体   English

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

[英]Strange behavior when casting numpy.float64 to float

I'm having the strangest behavior with an object generated by numpy.arange : 我对numpy.arange生成的对象有最奇怪的行为:

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

In this case, xo=1 , xn=4 , h=0.1 . 在这种情况下, xo=1xn=4h=0.1

Now, I expected xs[-1] to be exactly equal to 4.0 == float(4) . 现在,我预计xs[-1]正好等于4.0 == float(4) However, I get the following: 但是,我得到以下内容:

>>> 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

What on earth is happening here? 这到底发生了什么?

Placing print type(i) in the for loop prints <type 'numpy.float64'> . print type(i)放在for循环中打印<type 'numpy.float64'> Perhaps something going on during the float(i) casting? float(i)投射期间可能会发生什么? Using numpy.asscalar doesn't change anything. 使用numpy.asscalar不会改变任何东西。

Using math.ceil(foo) instead of sympy.ceiling(foo) issues the same thing (that's the part I actually need to work). 使用math.ceil(foo)而不是sympy.ceiling(foo)发出同样的事情(这是我实际需要工作的部分)。

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]

This is why you do not get the wanted result, due to floating point accuracy, it cant give True to your test. 这就是为什么你没有得到想要的结果,由于浮点精度,它不能给你的测试真实。 This also explains why if you do a round-operation like ceiling on it, that you get five instead of four. 这也解释了为什么如果你做一个像天花板这样的圆形操作,你会得到五个而不是四个。

edit: to check if x and y are the same (within some margin of error), you could do the following, but i think there is (should be) something already in python that can do this for you 编辑:检查x和y是否相同(在某个误差范围内),你可以做以下,但我认为(应该)已经在python中可以为你做这件事

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

edit2: or as ali_m said: edit2:或者作为ali_m说:

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

This is not really strange - it is just the way that floating point arithmetic works because it cannot represent most values exactly. 这并不奇怪 - 它只是浮点运算的工作方式,因为它无法准确表示大多数值。 If you do repeated computations in floating point ( arange() here is adding 0.1 to 1 and then adding 0.1 to that sum another 29 times) and if the numbers you are dealing with are not exactly representable in floating point, you won't get an exact answer at the end of the computation. 如果你以浮点重复计算( arange()这里加0.1到1然后再加上0.1加上另外29次)如果你正在处理的数字在浮点数上不能完全表示,你就不会得到计算结束时的确切答案。 The best article to read on this is What Every Computer Scientist Should Know About Floating-Point Arithmetic . 关于这一点的最佳文章是每个计算机科学家应该知道的关于浮点运算的内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM