Python “np.floor()”和float division的奇怪行为

Python “np.floor()”和float division的奇怪行为,python,numpy,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)]

这是怎么回事

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
得到的结果是0.9,或者至少与双精度浮点数的结果一样接近0.9:

>>> numpy.float64(0.9)
0.90000000000000002
0.9不能用有限的二进制分式数精确表示,因此必须对其进行近似

Python内置的浮点类型
float
总是试图找到将四舍五入到给定浮点数的最短十进制表示形式,从而试图隐藏问题。这就是为什么你会

>>> 0.9
0.9

在当前版本的Python中。早期版本(我认为2.6之前的版本)将向您显示与Numpy浮点数据类型相同的舍入值。

事实证明,与Python的
float
相比,Numpy有一种不同的算法将
float64
转换为字符串

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

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

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

因为最终,浮动(“0.9”)实际上正好等于0.9000000002220446049250313080847263336181640625。所以在某种意义上,两个答案都是正确的


问题与解答第二部分:您可以花时间了解浮点运算的工作原理,也可以在字典中使用整数桶


换句话说,与其使用
-1.0,-0.9,-0.8,…,0.9
,不如使用
-10,-9,-8,…,9
。它应该可以防止以后出现很多问题。

这与
地板
没有任何关系
np.int32(9)/10给出了相同的结果。“每一位计算机科学家都应该知道浮点运算”——这与
np.floor
无关。看看
np.float64(0.9)
。然后阅读但等待:
math.floor()
在提问者的同一代码上,行为不同,并打印0。9@NayukiMinase:这是由于Python内置的
float
类型和
numpy.float64
上的
实现不同。我扩展了我的答案。谢谢。我编辑了我的问题,因为即使我理解你的答案,我也不知道该怎么办。好的,我回答了你问题的第二部分。