Python中对负数的模运算


Answers:


136

与C或C ++不同,Python的模运算符(%)始终返回与分母(除数)具有相同符号的数字。您的表情产生3,因为

(-5)/ 4 = -1.25->下限(-1.25)= -2

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

之所以选择它是因为C行为,因为非负结果通常更有用。一个示例是计算工作日。如果今天是星期二(第2天),那么N天之前的星期几是什么?在Python中,我们可以使用

return (2 - N) % 7

但在C中,如果Ñ ≥3,我们得到这是一个无效的号码的负数,并且我们需要通过添加7手动修复它:

int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;

(有关如何确定不同语言的结果符号,请参见http://en.wikipedia.org/wiki/Modulo_operator。)


6
令人惊讶的是,Python的模运算符(%)并不 总是返回与分母(除数)具有相同符号的数字。参见stackoverflow.com/questions/48347515/…–
zezollo


9

没有最好的方法来处理带有负数的整数除法和mod。如果a/b幅值相同且符号相反,那就太好了(-a)/b。如果a % b确实是模b会很好。由于我们确实想要a == (a/b)*b + a%b,所以前两个是不兼容的。

保留哪个是一个难题,双方都有争论。C和C ++将整数除法取整为零(因此a/b == -((-a)/b)),而Python显然没有。


1
“如果a / b与(-a)/ b具有相同的大小和相反的符号,那就太好了。” 为什么那会很好?什么时候是期望的行为?
user76284 '19

因为它的作用方式与规则除法和乘法相同,因此直观上易于使用。从数学上讲,这可能没有任何意义。
Demis

6

如前所述,Python模数是其他语言约定的合理理由

这使负数具有无缝的行为,尤其是在与//整数除法运算符结合使用时,尤其是%模(例如,在math。divmod中):

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%始终输出零或正数*
  • Python//总是四舍五入为负无穷大

* ...只要正确的操作数为正。另一方面11 % -10 == -9


谢谢你的榜样让我明白了:)
Lamis

5

python中,模运算符的工作原理如下。

>>> mod = n - math.floor(n/base) * base

因此结果是(针对您的情况):

mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3

而其他语言(例如C,JAVA,JavaScript)则使用截断而不是floor。

>>> mod = n - int(n/base) * base

结果是:

mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1

如果您需要有关python取整的更多信息,请阅读this


3

模数,等价类为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 ...

这是带有负数的模的行为的链接。(是的,我用谷歌搜索了)


@NullUserException-是的。固定。谢谢。
小麦色的

1

我还认为这是Python的奇怪行为。事实证明,我没有很好地解决这一分歧(在纸上);我给商的值是0,余数是-5。糟糕...我忘记了整数的几何表示。通过调用数字线给出的整数的几何形状,可以得到商和余数的正确值,并检查Python的行为是否正确。(尽管我认为您早已解决了您的问题)。


1

还值得一提的是,python中的除法也不同于C:请考虑

>>> x = -10
>>> y = 37

在C中,您期望结果

0

python中的x / y是什么?

>>> print x/y
-1

%是模数-不是余数!尽管x%y的C产量

-10

python产量。

>>> print x%y
27

您可以像在C中一样获得两者

部门:

>>> from math import trunc
>>> d = trunc(float(x)/y)
>>> print d
0

其余的(使用上面的划分):

>>> r = x - d*y
>>> print r
-10

这种计算可能不是最快的,但它适用于x和y的任何符号组合,以达到与C中相同的结果,而且它避免了条件语句。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.