Python中的负数模

我在python中发现了一些关于负数的奇怪行为:

>>> a = -5 >>> a % 4 3 

任何人都可以解释发生了什么事?

与C或C ++不同,Python的模运算符( % )总是返回一个与分母(除数)符号相同的数字。 你的expression产生3,因为

(-5)%4 =( – 2×4 + 3)%4 = 3。

它被select在C行为上,因为非负面的结果通常更有用。 一个例子是计算星期几。 如果今天是星期二(第二天),那么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关于如何确定不同语言的结果符号。);

以下是Guido van Rossum的解释:

http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html

本质上,a / b = q的余数r保留了b * q + r = a和0 <= r <b的关系。

没有最好的方法来处理整数除法和负数的mods。 如果a/b(-a)/b的相同的幅度和相反的符号,那将是很好的。 如果a % b确实是一个模b,那将会很好。 既然我们真的想要a == (a/b)*b + a%b ,前两个是不兼容的。

要保留哪一个是一个困难的问题,双方都有争议。 C和C ++的整数除以零(如此a/b == -((-a)/b) ),显然Python不是。

模数,等价类为4:

  • 0:0,4,8,12 …和-4,-8,-12 …
  • 1:1,5,9,13 …和-3,-7,-11 …
  • 2:2,6,10 …和-2,-6,-10 …
  • 3:3,7,11 …和-1,-5,-9 …

这里是一个模数与负数联系的行为 。 (是的,我GOOGLE了)

正如所指出的那样,Python模块对其他语言的约定做出了合理的例外。 这给负数提供了一个无缝的行为,尤其是当与整数除法运算符结合使用时,由于%模常常是(如在mathdivmod中 ):

 for n in range(-8,8): print n, n//4, n%4 

生产:

  -8 -2 0 -7 -2 1 -6 -2 2 -5 -2 3 -4 -1 0 -3 -1 1 -2 -1 2 -1 -1 3 0 0 0 1 0 1 2 0 2 3 0 3 4 1 0 5 1 1 6 1 2 7 1 3 

我也认为这是Python的一个奇怪的行为。 事实certificate,我没有很好地解决这个问题(在纸上)。 我给商的值是0,其余的是-5。 可怕的…我忘记了整数数字的几何表示。 通过回顾数字行给出的整数几何,可以得到商和余数的正确值,并检查Python的行为是否正确。 (虽然我认为你很早以前就已经解决了你的问题)。