具有负值的模量运算-很奇怪吗?

时间:2020-03-05 18:47:36  来源:igfitidea点击:

你能告诉我(-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)