请问(-2) % 5的计算结果是多少?据我的Python解释器显示为3,但您能不能对此进行简明扼要的解释呢?
我读过一些关于某些语言中结果可能依赖于机器的说法,但我不确定这是否正确。
顺便说一下:大多数编程语言会与Python不同,并显示结果-2
。根据模运算的解释,这是正确的。然而,大多数人认可的数学定义规定,a和b的模是它们相除产生的(严格为正的)余数r。更准确地说,根据定义,0 <= r < b。
你的Python解释器是正确的。
一种(愚蠢的)计算模数的方法是不断加减模数,直到结果的值在0和(模数-1)之间。
例如:13 mod 5 = (13 − 5) mod 5 = (13 − 10) mod 5 = 3
或者在你的情况下:-2 mod 5 = (-2 + 5) mod 5 = 3
b * (a/b) + a%b == a
。如果除法向负无穷舍入(如Python中所示),则余数应始终为正数。 - augurar如Python文档在二进制算术运算中所述,Python确保:
整数除法和取模运算符通过以下恒等式相互关联:
x == (x/y)*y + (x%y)
。 整数除法和取模还与内置函数divmod()相关联:divmod(x, y) == (x/y, x%y)
。
事实上,
>>> divmod(-2, 5)
(-1, 3).
另一种展示该方法统一性的方式是计算一小组数字的divmod
:
>>> for number in xrange(-10, 10):
... print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)
那么,0%5应该是0,对吗?
-1%5应该是4,因为这是沿相反方向的下一个允许数字(即不能是5,因为它超出了范围)。
按照这个逻辑进行下去,-2必须是3。
最简单的想法是,你不断地加上或减去5,直到数字落在0(包括)和5(不包括)之间。
我不确定机器的依赖性 - 我从来没有见过这样的实现,但我不能说它从来没有被做过。
这是Python所采用的选择。基本上,模运算被定义为始终满足以下条件:模运算符始终生成与其第二个操作数(或零)相同符号的结果;结果的绝对值严格小于第二个操作数的绝对值。
x == (x/y)*y + (x%y)
在编程中,“模数”和“余数”的术语经常会引起混淆。
在数学中,余数应始终与商一致定义,因此如果 a / b == c rem d
,则 (c * b) + d == a
。根据商的舍入方式不同,得到的余数也不同。
然而,模数应始终给出一个结果 0 <= r < divisor
,这只有在允许负整数时才与向负无穷大除法一致。如果除法向零舍入(这很常见),则模数和余数仅对非负值等效。
一些语言(特别是 C 和 C++)没有定义所需的舍入/余数行为,%
是不明确的。许多语言将舍入定义为向零舍入,但使用模数一词,而余数更正确。Python 相对不寻常,因为它向负无穷大舍入,所以模数和余数是等效的。
Ada 向零舍入,但具有 mod
和 rem
运算符。
C语言的策略旨在让编译器为机器选择最有效的实现方式,但在我看来这是一种错误的优化,至少在现今时代如此。一个好的编译器可能会能够在负数无法出现的任何地方使用等价性进行优化(而且几乎肯定会使用无符号类型)。另一方面,在负数可能出现的情况下,你几乎肯定关心细节 - 由于可移植性原因,你必须使用设计非常谨慎的过分复杂的算法和/或检查来确保你获得想要的结果,无论舍入和余数行为如何。
换句话说,这种“优化”的收益大多数情况下(如果不总是)都是一种错觉,而在某些情况下有非常真实的成本 - 因此它是一种虚假的优化。
嗯,-2除以5的结果是0,余数为3。我不认为这应该与平台有太大关系,但我见过更奇怪的事情。
结果取决于编程语言。Python 返回除数的符号,而例如 c# 返回被除数的符号(即 -2 % 5 在 c# 中返回 -2)。
math.fmod
来获得与 C 或 Java 相同的行为。 - 0x2b3bfa0