Python 中的模数令人困惑。
在 Python 中,%
运算符计算余数:
>>> 9 % 5
4
然而:
>>> -9 % 5
1
为什么是结果1
?而不是-4
?
Python 中的模数令人困惑。
在 Python 中,%
运算符计算余数:
>>> 9 % 5
4
然而:
>>> -9 % 5
1
为什么是结果1
?而不是-4
?
-10 % 5 为 0,即 -10 除以 5。
你问为什么 -9 % 5 不是 -4,答案是 1 和 -4 都可以是正确答案,这取决于 -9 除以 5 是多少。当然 -9 除以 5 是 1.8,但是这是整数除法,在 Python 3 中用 // 表示,所以我这里用 // 来明确我们说的是整数除法。
我将通过不使用负数来解释这一点,它更容易。
9 // 5 是 1。也就是说,你只能从 9 中减去 5 1 次,剩下的就是 4。但是如果你再从 9 中减去 5 一次,那么剩下的就变成了 -1!
所以 -1 是 9 % 5 的正确答案,如果 9 // 5 是 2。
在 Python 9 中 // 5 是 1,因为 Python 整数除法是一个下除法,即它总是向下舍入。如果四舍五入9 // 5 将是 2,而 9 % 5 将是 -1。
现在让我们看看使用负数的情况:-9 除以 5 现在是 -2。因为是楼层划分,所以总是四舍五入。这意味着其余的是 1。所以 -9 % 5 是 1,而不是 -4。
这确实与 python 如何舍入整数除法有关。
在数学上,对于任何 int x 和 y,以下必须始终为真
x == (x // y) * y + x % y
所以从这里,我们可以说
x % y == x - (x // y) * y
现在回想一下,python 将整数除法四舍五入到负无穷,而不是零。例如 -9 // 5 给出 -2,而不是 -1。使用此逻辑,您将获得 -9 % 5 = 1
这样想:
0 % 5 为 0
1 % 5 是 1
所以……如果你倒退怎么办?
-1 % 5 必须是 4
-2 % 5 必须是 3
等等。
你会看到下面这个 -9 % 5 is 1
注意:根据编程语言和 % 的实现,您可能会得到不同的结果,因为程序员在如何处理 % 中的负数上存在分歧
在整数中,您不能总是选择quotient * divisor == dividend
. 如果product
不等于dividend
,则总是要做出选择,是使其略小于dividend
,还是略大于dividend
。product
与的总和remainder
使dividend
,这remainder
就是。无论如何,股息和产品必须接近,这意味着余数的绝对值必须小于除数的绝对值。
当divisor
为正时,products
增加为quotients
增加;当divisor
为负数时,products
随着quotients
增加而减少。在第一种情况下,产品从下面走,在第二种情况下,产品从上面走。在 Python 中,在这两种情况下quotient
,只有在dividend
达到下一个可能时才会采用下一个product
,这与产品的运行方式相同。在此之前,只有remainder
为适应下一个而进行的更改dividend
,再次始终与股息变化的方向相同,而不会在零处中断。这条规则在 Python 中是通用的,它始终成立。
这不是做出这种选择的原因,但它给出了会发生什么的想法(即为什么结果是这样的,以及预期的结果)。