我之前在(天真)假设模数运算符返回除法的余数。我显然是错的,因为-2%5返回3.我会认为5除以-2为零,其余为-2。
现在我理解了如何执行此操作的机制,但我的问题是为什么?有人可以给我一些链接,解释为什么模数和余数不是同义词,或者是一个有用的情况的例子吗?
答案 0 :(得分:3)
结果完全正确。模块化算术定义以下(我将使用“congruent”,因为我不能用三行键入等号)
一致的b mod c iff a-b是c的倍数,即对于某个整数x,x * c =(a-b)。
E.g。
0 congruent 0 mod 5 (0 * 5 = 0-0)
1 congruent 1 mod 5 (0 * 5 = 1-1)
2 congruent 2 mod 5 (0 * 5 = 2-2)
3 congruent 3 mod 5 (0 * 5 = 3-3)
4 congruent 4 mod 5 (0 * 5 = 4-4)
5 congruent 0 mod 5 (1 * 5 = 5-0)
6 congruent 1 mod 5 (1 * 5 = 6-1)
...
同样可以扩展到负整数:
-1 congruent 4 mod 5 (-1 * 5 = -1-4)
-2 congruent 3 mod 5 (-1 * 5 = -2-3)
-3 congruent 2 mod 5 (-1 * 5 = -3-2)
-4 congruent 1 mod 5 (-1 * 5 = -4-1)
-5 congruent 5 mod 5 (-1 * 5 = -5-0)
-6 congruent 4 mod 5 (-2 * 5 = -6-4)
-7 congruent 3 mod 5 (-2 * 5 = -7-3)
...
正如你所看到的,很多整数是全等的3 mod 5: ......, - 12,-7,-2,3,8,13 ......
在数学中,这些数字的集合被称为由等价关系“同余”引起的等价类。我们对余数的理解和“mod”函数的定义都是基于这个等价类。 “余数”或mod计算的结果是等价类的代表性元素。通过声明,我们选择了最小的非负元素(因此-2不是有效的候选者)。
因此,当您阅读-2 mod 5 = x时,这将转换为“查找最小的非负x,以便存在y * 5 = -2 - x的整数y”,与同余的定义一致。解决方案是y = 1和x = 3,你可以通过简单地尝试y的其他值来看到。
答案 1 :(得分:2)
a = n (mod m)
定义为a = n + m*t
,它同样适用于负数。 (另一个看待它的是a = n (mod m)
表示(a - n)
是m
的倍数
-2 = 3(mod 5)因为-2 = 3-5(即t = -1)
惯例是取modulo m
的结果是0到m-1(含)之间的数字
答案 2 :(得分:1)
您获得的基本保证是
(a % b) + b * (a / b) == a
对于有符号值,没有理由将这两个符号作为模运算或除法运算的首选结果。有些语言修复了一种形式,有些则将其留给实现,因此实现可以使用硬件提供的任何方式。反过来,可能已选择硬件指令来有效地操作硬件对有符号整数的表示。
通常,在将有符号整数与除法,余数和位移操作一起使用时要非常小心。
答案 3 :(得分:0)
将modulo想象为一个操作符,它围绕一个x pegs圆圈包裹一条长度为y的线(以y%x表示)。没有完全环绕x的线的剩余长度是结果。
答案 4 :(得分:0)
我想这取决于你是希望你的结果向下舍入还是向0舍入:
2 / 5 = 0.4 = 5*0 + 2
适用于这两种情况,而
-2 / 5 = -0.4 = 5*0 + -2
如果你向0(截断)四舍五入,则
-2 / 5 = -0.4 = 5*-1 + 3
如果你正在向下(地板)。
请注意,在第二种情况下,结果始终为正(对于正除数),例如,在计算数组索引时,它会很有用:
hashmapBuckets[getIntHash(obj) % hashmapBuckets.size].add(obj)
或规范角度:
angle = angle % 360; //0-359
事实上,另一种情况是我无法找到实际例子:)
-
哦,Wikipedia page on the modulo operation有一些不错的图表。请注意,余数始终与分层除数的符号相同。