`np.floor()`和浮点除法的奇怪行为

时间:2015-08-30 20:31:24

标签: python numpy

这里发生了什么?

In [86]:  np.floor(10.0 * .91)
Out[86]:  9.0

In [87]:  np.floor(10.0 * .91)/10.0
Out[87]:  0.90000000000000002

为什么不0.9

编辑:

我想做这样的事情:

#create 2d bins
bins = {}
for x in np.arange(-1,1, 0.1):
    for y in np.arange(-1,1, 0.1):
        bins[(x,y)] = 0

#count number of occurences in each bin
for x,y in np.random.randn(10,2):
    rounded = (np.floor(10.0 * x)/10.0, np.floor(10.0 * y)/10.0)
    bins[(x,y)] += 1   # I get an error here

2 个答案:

答案 0 :(得分:0)

的结果是 0.9,或者至少与双精度浮点数一样接近0.9:

>>> numpy.float64(0.9)
0.90000000000000002

0.9无法精确表示为有限二进制分数,因此必须近似。

Python的内置浮点类型float试图通过总是尝试找到将舍入到给定浮点数的最短十进制表示来隐藏问题。这就是你得到的原因

>>> 0.9
0.9

在当前版本的Python中。早期版本(我认为高达2.6)会显示你为Numpy的浮点数据类型获得的相同舍入值。

答案 1 :(得分:0)

事实证明,与Python的float64相比,numpy将float转换为字符串的算法不同。

当字符串0.90000000000000002和0.9被解析为float64时,它们最终具有相同的位模式。

您可以确认np.floor(10.0 * .91)/10.0 == 0.9会产生True

这里的根本问题是,当将float转换为字符串时,应该给出多少小数位?某些实现使用最小位数,以便将字符串解析为最接近的浮点值将产生相同的值。有些实现会为安全性提供额外的数字。

因为最终,float(“0.9”)实际上完全等于0.90000000000000002220446049250313080847263336181640625。所以从某种意义上说,两个答案都是正确的。

Q&第二部分:你可以花时间搞清楚浮点的工作原理,或者你可以使用整数桶作为你的字典。

换句话说,取而代之的是-1.0, -0.9, -0.8, ..., 0.9之类的密钥,而不是密钥-10, -9, -8, ..., 9。这应该可以防止很多问题。