Python中对负数的模运算

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3883004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:10:41  来源:igfitidea点击:

The modulo operation on negative numbers in Python

pythonmodulonegative-number

提问by facha

I've found some strange behaviour in Python regarding negative numbers:

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

>>> -5 % 4
3

Could anyone explain what's going on?

谁能解释一下这是怎么回事?

采纳答案by kennytm

Unlike C or C++, Python's modulo operator (%) always return a number having the same sign as the denominator (divisor). Your expression yields 3 because

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

(-5) / 4 = -1.25 --> floor(-1.25) = -2

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

(-5) / 4 = -1.25 --> 楼层(-1.25) = -2

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

It is chosen over the C behavior because a nonnegative result is often more useful. An example is to compute week days. If today is Tuesday (day #2), what is the week day Ndays before? In Python we can compute with

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

return (2 - N) % 7

but in C, if N≥ 3, we get a negative number which is an invalid number, and we need to manually fix it up by adding 7:

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

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

(See http://en.wikipedia.org/wiki/Modulo_operatorfor how the sign of result is determined for different languages.)

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

回答by Kevin

Here's an explanation from Guido van Rossum:

以下是 Guido van Rossum 的解释:

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

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

Essentially, it's so that a/b = q with remainder r preserves the relationships b*q + r = a and 0 <= r < b.

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

回答by wheaties

Modulo, equivalence classes for 4:

模数,4 的等价类:

  • 0: 0, 4, 8, 12... and -4, -8, -12...
  • 1: 1, 5, 9, 13... and -3, -7, -11...
  • 2: 2, 6, 10... and -2, -6, -10...
  • 3: 3, 7, 11... and -1, -5, -9...
  • 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...

Here's a link to modulo's behavior with negative numbers. (Yes, I googled it)

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

回答by David Thornley

There is no one best way to handle integer division and mods with negative numbers. It would be nice if a/bwas the same magnitude and opposite sign of (-a)/b. It would be nice if a % bwas indeed a modulo b. Since we really want a == (a/b)*b + a%b, the first two are incompatible.

没有一种最好的方法来处理整数除法和负数的 mods。如果a/b的大小相同且符号相反,那就太好了(-a)/b。如果a % b确实是模 b那就太好了。既然我们真的想要a == (a/b)*b + a%b,前两者是不兼容的。

Which one to keep is a difficult question, and there are arguments for both sides. C and C++ round integer division towards zero (so a/b == -((-a)/b)), and apparently Python doesn't.

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

回答by Bob Stein

As pointed out, Python modulo makes a well-reasonedexception to the conventions of other languages.

正如所指出的,Python modulo为其他语言的约定提供了一个合理的例外。

This gives negative numbers a seamless behavior, especially when used in combination with the //integer-divide operator, as %modulo often is (as in math.divmod):

这为负数提供了无缝行为,尤其是与//整数除法运算符结合使用时,因为%模通常是(如在math.divmod 中):

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

Produces:

产生:

 -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 %always outputs zero or positive when the divisor is positive
  • Python //always rounds toward negative infinity
  • %当除数为正数时,Python总是输出零或正数
  • Python//总是向负无穷大舍入

回答by joser

I also thought it was a strange behavior of Python. It turns out that I was not solving the division well (on paper); I was giving a value of 0 to the quotient and a value of -5 to the remainder. Terrible... I forgot the geometric representation of integers numbers. By recalling the geometry of integers given by the number line, one can get the correct values for the quotient and the remainder, and check that Python's behavior is fine. (Although I assume that you have already resolved your concern a long time ago).

我还认为这是 Python 的一种奇怪行为。事实证明,我没有很好地解决除法问题(在纸上);我给商一个值 0,给余数一个值 -5。太可怕了……我忘记了整数的几何表示。通过回忆数轴给出的整数几何,可以得到商和余数的正确值,并检查 Python 的行为是否正常。(虽然我假设您很久以前就已经解决了您的问题)。

回答by bebbo

It's also worth to mention that also the division in python is different from C: Consider

还值得一提的是,python 中的划分也与 C 不同:考虑

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

in C you expect the result

在 C 中你期望结果

0

what is x/y in python?

python中的x/y是什么?

>>> print x/y
-1

and % is modulo - not the remainder! While x%y in C yields

和 % 是模数 - 不是余数!而 C 中的 x%y 产生

-10

python yields.

蟒蛇产量。

>>> print x%y
27

You can get both as in C

你可以在 C 中同时获得

The division:

分工:

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

And the remainder (using the division from above):

余数(使用上面的除法):

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

This calculation is maybe not the fastest but it's working for any sign combinations of x and y to achieve the same results as in C plus it avoids conditional statements.

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

回答by Munkhbold Enkhtur

In python, modulo operator works like this.

在python中,模运算符的工作方式是这样的。

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

so the result is (for your case).

所以结果是(对于你的情况)。

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

whereas other languages such as C, JAVA, JavaScript are used trunc instead of floor.

而其他语言如 C、JAVA、JavaScript 则使用 trunc 而不是 floor。

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

If you need more information about rounding in python, read this

如果您需要有关 Python 中舍入的更多信息,请阅读此内容