modulus的工作原理是什么,为什么Python与大多数语言不同?

7 投票
3 回答
786 浏览
提问于 2025-04-17 13:10

下面是一些用 C++写的代码。如果你在Python中尝试 -2%5,结果会是正数3,而很多其他语言,比如C++和C#(代码)以及Flash,结果却是-2。

为什么会出现-2的结果?这两种结果哪个更正确呢?

#include <cstdio>
int main(){
printf("%d\n", 2%5);
printf("%d\n", -2%5);
printf("%d\n", -2%77);
printf("%d\n", 2%-77);
printf("%d\n", -2%-77);
}

输出:

2
-2
-2
2
-2

3 个回答

-1

我觉得你应该看看下面的内容。除了使用稍微不同的算法之外,运算符的优先级也很重要。试着用括号来看看效果:

In [170]: 2%5
Out[170]: 2

In [171]: -2%5
Out[171]: 3

In [172]: (-2)%5
Out[172]: 3

In [173]: -(2%5)
Out[173]: -2
2

根据C++的文档

对于负数,结果可能会根据不同的库实现而有所不同。

这听起来有点奇怪。而Python的文档只说了这一点:

取模运算符的结果总是和第二个操作数有相同的符号(或者是零);结果的绝对值严格小于第二个操作数的绝对值。

我觉得Python的方式似乎更合理,但这只是我的一种直觉。

7

如果 r = a % n,那么可以写成 a = n * q + r,其中 q 是某个数。这意味着 r 的值有很多选择,具体取决于你选择的 q 的值。

我建议你去看看 这个链接,上面提到大多数编程语言会选择 r 的范围是 -n < r < n。这就意味着,除非 r 是零,否则 r 有两个选择:一个是正数,一个是负数。不同的编程语言在选择正数还是负数时会有不同的规则。你可以在那个页面找到一个表格,总结了不同语言的做法:

  • Python 选择的 rn 有相同的符号(就像上面看到的那样)。
  • C++ 2011 选择的 ra 有相同的符号(在2011标准之前,这个是由实现决定的)。

如果你想在 Python 中确保得到正数,可以使用下面的代码:

r = a % n
if r < 0:
  r += n

撰写回答