具有负值的模量运算-很奇怪吗?
你能告诉我(-2)%5
是多少吗?
根据我的Python解释器,值为3,但是我们对此有一个明智的解释吗?
我读过某些语言的结果可能与机器有关,但是我不确定。
解决方案
回答
Python解释器是正确的。
一种计算模数的(愚蠢的)方法是减去或者相加模数,直到结果值介于0和(模数≥1)之间。
例如。:
13 mod 5 =(13?5)mod 5 =(13?10)mod 5 = 3
或者情况:?2 mod 5 =(?2 + 5)mod 5 = 3
回答
好吧,-2除以5等于0,其余为3. 我不认为这应该与平台有关,但是我已经看到了一些奇怪的东西。
回答
的确是3. 在模算术中,模数只是除法的余数,而-2除以5的余数是3.
回答
对负数进行模运算的结果似乎与编程语言有关,下面是列表http://en.wikipedia.org/wiki/Modulo_operation
回答
好吧,0%5应该是0,对不对?
-1%5应该为4,因为这是下一个允许的相反方向数字(即,不能为5,因为这超出了范围)。
遵循该逻辑,-2必须为3.
考虑它如何工作的最简单方法是,我们不断增加或者减少5,直到数字介于0(含)和5(不含)之间。
我不确定机器依赖性,我从未见过这样的实现,但是我不能说它从未完成。
回答
顺便说一句:大多数编程语言会不同意Python并给出结果" -2"。根据模量的解释,这是正确的。但是,最公认的数学定义是a和b的模数是a / b除法的(严格为正)余数r。更确切地说,0 <= r <b定义为。
回答
结果取决于语言。 Python返回除数的符号,例如,递减除数的符号(即-2%5在c#中返回-2)。
回答
一种解释可能是负数使用2的补码存储。当python解释器尝试执行模运算时,它将转换为无符号值。因此,实际上不是计算(-2)%5,而是计算0xFFFF_FFFF_FFFF_FFFD%5,即3.
回答
如其他答案所述,对于具有负值的模运算,有很多选择。通常,不同的语言(和不同的机器体系结构)将给出不同的结果。
根据Python参考手册,
The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand.
是Python采取的选择。基本上定义了模,以便始终保持:
x == (x/y)*y + (x%y)
因此有意义的是(-2)%5 = -2(-2/5)* 5 = 3
回答
注意不要在所有操作系统和体系结构上都依赖于C / C ++中的这种mod行为。如果我没记错的话,我尝试依赖C / C ++代码,例如
float x2 = x % n;
将x2的范围保持在0到n-1之间,但是当我在一个OS上进行编译时,负数会逐渐增加,但是在另一个OS上可以正常工作。由于调试只发生一半的时间,因此调试很麻烦!
回答
就像文档在二进制算术运算中所说的那样,Python确保:
The integer division and modulo operators are connected by the following identity: x == (x/y)*y + (x%y). Integer division and modulo are also connected with the built-in function 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)