我一直在阅读关于Python中除法和整数除法以及Python2与Python3之间差异的内容。大部分都很容易理解。当两个值都是整数时,Python 2仅使用整数除法,而Python 3总是执行真实的除法。 Python 2.2+引入了用于整数除法的//
运算符。
其他程序员提供的示例非常好,例如:
>>> 1.0 // 2.0 # floors result, returns float
0.0
>>> -1 // 2 # negatives are still floored
-1
如何实现//
?为什么会发生以下情况:
>>> import math
>>> x = 0.5
>>> y = 0.1
>>> x / y
5.0
>>> math.floor(x/y)
5.0
>>> x // y
4.0
为什么不写成 x // y = math.floor(x/y)
呢?这些结果是在 Python 2.7 上生成的,但由于 x 和 y 都是浮点数,在 Python 3+ 上结果应该是相同的。如果存在某种浮点误差,使得 x/y
实际上是 4.999999999999999
,并且 math.floor(4.999999999999999) == 4.0
,那么这不会反映在 x/y
吗?
然而,以下类似情况不受影响:
>>> (.5*10) // (.1*10)
5.0
>>> .1 // .1
1.0
a // b
而不是math.floor(a, b)
,我看不到文档承认这一点,而PEP关于//
语义的陈述似乎明显是不正确的。如果您感兴趣,我已在答案中添加了相关说明。 - jme.5 // .1
不等同于floor((.5 - mod(.5, .1)) / .1)
;当你阅读源代码时,你可能会错过floordiv = floor(div);
后面直接跟着if (div - floordiv > 0.5) floordiv += 1.0;
的部分。这意味着它进行四舍五入而不是向下取整。 - user23571124.0
是正确舍入的结果 - 也就是说,如果你取两个浮点数输入.5
和.1
所代表的实数(而不是实际的数字.5和.1),应用理想的数学函数f(x, y) = floor(x/y)而没有中间舍入,然后选择最接近实数结果的浮点数作为返回值,那么你会得到4.0
。我还没有分析过floordiv实现是否比应用浮点除法和浮点floor更频繁地产生正确舍入的结果... - user2357112.5 / .1
的特定情况下,if
语句的四舍五入分支不会被执行,但你说得对,通常结果是四舍五入而不是向下取整。我会更新我的答案以澄清这一点。谢谢! - jme