整数除法与向下取整商的比较:为什么会有这个惊人的结果?

10

今天,Python 的 // “整数除法” 运算符让我感到惊讶:

>>> math.floor(11/1.1)
10.0
>>> 11//1.1
9.0
文档中写道:“x和y的(向下取整的)商”。那么,为什么math.floor(11/1.1)等于10,但11//1.1等于9呢?

5
很抱歉,我无法访问该网页或进行翻译。请提供需要翻译的具体内容,我会尽力为您提供帮助。 - miku
Python 2和3之间的除法差异的规范问题是如何在Python中强制执行浮点除法?除法一直向下舍入为0 - smci
1个回答

7

因为1.1在二进制形式下无法精确表示;近似值比1.1略高,因此除法结果会偏小。

请尝试以下方法:

在Python 2下,在控制台中键入:

>>> 1.1
1.1000000000000001

在Python 3.1中,控制台将显示1.1,但在内部,它仍然是相同的数字。
但是:
>>> 11/1.1
10.0

作为gnibbler指出的,这是在浮点数可用精度限制内进行“内部舍入”的结果。正如The MYYN在他的评论中指出的那样,//使用不同的算法来计算地板除法结果,以尽可能保留a == (a//b)*b + a%b
如果需要更高的精度,请使用Decimal类型。

但是根据Python的语法,11.0 / 1.1 == 10.0 是成立的。 - sth
1
正如我们所知,1.1被存储为1.1000000000000001,因此在Python中,11.0/1.1的结果为9.999999999999999090909090909,但最接近这个数字的浮点数实际上是10.0,因此结果恰好是10.0。 - John La Rooy
@Tim 我考虑过这个问题,我相信这就是 math.floor(11/1.1) 和 11//1.1 之间差异的关键。然而,正如 gnibbler 指出的那样,1.1 被表示成一个稍微大一点的数只是说明 math.floor(11/1.1) 应该真正为 9.0,这仍然没有回答最初的问题。 - Eric O. Lebigot
1
@EOL,自11/1.1以来评估为确切的10.0,math.floor(11/1.1)=math.floor(10.0),但这仅仅是由于舍入运算有些幸运。 - John La Rooy
1
@gnibbler:是啊,让我惊讶的是“运气”这个方面:两个“相同”的操作表现出不同的行为。:) 这种解释在实现中,正如The MYYN所指出的。 - Eric O. Lebigot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接