为什么Python和Java中的%运算符表现不同?

4

Python 2.7.1:

print -34 % 4 # outputs 2

Java 1.5.0:

System.out.println(-34 % 4); // outputs -2

哪一个是正确的?为什么会有差异?

wikipedia article on modulo上说:

当a或n中有一个为负数时,这个朴素的定义就会失效,编程语言在如何定义这些值上存在差异。

也许这不是一个适当的SO问题,可能会被删除,但我很想看到回复。


1
我猜这只是实现的特定问题。编程语言选择如何定义它。关于负数取模的正确答案存在争议,这可能就是原因。 - Jesus Ramos
你期望什么样的答案?唯一的答案是他们设计得不同,或者其中一个或两个人都弄错了。 - user207421
4个回答

6

这只是语言选择的一种约定。没有一种选择比另一种更数学上正确。

Python的选择原因可以在源代码中找到提示: http://hg.python.org/cpython/file/2.7/Objects/intobject.c#l567

Python版本在数论中更常用。Java版本实现与C相同的行为。Python方式很方便,因为结果的符号始终与除数的符号相同。这意味着当n为正数时,x%n始终给出0 <= result < n的值。

我推测像C这样的低级语言使用不同的约定的原因是它更接近机器语言,在机器语言中返回与n有符号除法相同的结果(例如参见IDIV)。如果C采用了数论约定,它就需要编译额外的指令来比较结果的符号和除数的符号,如果它们不匹配,则跳转到附加代码以将除数添加或减去结果(换句话说,C采用了对应于最小努力的约定)。

2
我非常确定C语言的原始“规范”没有说明在这种情况下会发生什么,而是留给实现者决定。 - Stephen C
1
看到为了将整数除法这样看似微不足道的东西包装起来以适应更高级别的语言而需要付出多少努力,真是有点痛苦。 - Karl Knechtel

0

这是因为两种语言的编程方式不同。

Java在应用模数(%)运算符时会考虑分子的符号,而Python则不会。

如果您在分母上写入“-”符号,即使是Java也会忽略它。


0
为什么Python和Java中的%运算符不同?
简单来说,因为Python不是Java,它们之间的差异之一就是你从维基百科文章中引用的那个。 :)
但是,说真的,这是一个相当任意的选择;其中一个定义在某些情况下更有用,而另一个在其他情况下更有用。庆幸你正在使用一种选择了一个定义的语言,而不是只使用CPU上最快的东西;)

-1
在 C/C++ 中,结果为 -2。所以我想这就是为什么 Java 走了另一条路。它们在一开始非常希望吸引 C++ 开发人员。

C和C++是具有不同规范的不同语言。在C++和C89中,它是实现定义的。在C99中,它与Java相同。这在OP链接的维基百科文章中有所涵盖。至于动机,针对吸引C++程序员的所有事情中,我非常怀疑这是列表上的一项。 - Karl Knechtel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接