Python中负数的取模(%)运算是如何工作的?
在Python中,%
这个符号叫做取余运算符,它的作用是计算一个数除以另一个数后,剩下的部分。简单来说,就是看一个数在被另一个数整除后,还剩下多少。
那么,当涉及到负数时,它的工作方式可能会让人感到困惑。比如说,为什么-5 % 4
的结果是3
,而不是-1
呢?
其实,这和取余的定义有关。在Python中,取余的结果总是会是一个非负数,也就是说,它的结果总是大于或等于0。这是为了让计算结果更一致和易于理解。
所以,当你计算-5 % 4
时,实际上是在问:如果把-5除以4,剩下的部分是什么?在这种情况下,-5可以被看作是-8加上3(因为-8是4的一个倍数),所以余数就是3。
12 个回答
其他的回答,特别是被选中的那个,已经很好地回答了这个问题。但我想用一种图形化的方法来解释,这样可能更容易理解,同时也会提供一些Python代码来进行普通的数学取模运算。
Python取模简单易懂版
取模函数是一个方向性的函数,它描述了在我们进行除法时,在无限数字的X轴上,我们需要向前或向后移动多少。比如说,你在计算 7%3
。
在向前的方向上,你的答案是+1,但在向后的方向上-
你的答案是-2。这两种答案在数学上都是正确的 数学上。
同样,对于负数,你也会有两个取模结果。例如:-7%3
,可以得到-1或+2,如下所示-
向前的方向
向后的方向
在数学中,我们选择向内跳跃,也就是对于正数选择向前方向,对于负数选择向后方向。
但在Python中,所有正数的取模运算都是向前的方向。因此,你可能会感到困惑-
>>> -5 % 4
3
>>> 5 % 4
1
这里是Python中向内跳跃类型的取模代码:
def newMod(a,b):
res = a%b
return res if not res else res-b if a<0 else res
这将给出-
>>> newMod(-5,4)
-1
>>> newMod(5,4)
1
很多人可能会反对这种向内跳跃的方法,但我个人认为,这种方法更好!!
这是Guido van Rossum的解释:
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
简单来说,这样做是为了确保当你用a去除以b时,得到的结果q和余数r能够保持这样的关系:b乘以q加上r等于a,并且r的值要在0到b之间。
跟C或C++不一样,Python的取模运算符(%
)总是返回一个和除数(也就是分母)符号相同的数字。你得到3的原因是:
(-5) / 4 = -1.25 --> 向下取整(-1.25) = -2
(-5) % 4 = (-2 × 4 + 3) % 4 = 3。
选择这种方式是因为非负的结果通常更有用。举个例子,计算星期几。如果今天是星期二(第2天),那么N天前是星期几呢?在Python中,我们可以这样计算:
return (2 - N) % 7
但在C语言中,如果N ≥ 3,我们会得到一个负数,这个负数是无效的,我们需要手动加7来修正:
int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;
(想了解不同语言中结果符号是如何确定的,可以查看http://en.wikipedia.org/wiki/Modulo_operator。)