先说结论:因为对质数取模之后的结果发生碰撞概率更小。
- 很多时候为了解决数字超过存储上限问题,我们可以对该数取模然后存储,这就导致不同的数字可能取模后结果一致,也就是发生了碰撞,这时我们就需要对比原数字。
- 首先,在求余数的时候,例如:
a%b
,我们希望取余后的数有可能是0-(b-1)
之间任意的一个数,这样才能最大化取余之后的映射空间,减少碰撞- 而如果
a
,b
有公约数c
,那么取余后的结果只会是c的倍数:0,c,2c,3c等等,而取不到1-(c-1)
,(c+1)-(2c-1)
中间的数,大大减少了映射空间 - 例如:
25%10=5
,25%15=10
,25%20=5
等等
- 而如果
- 那么这是为何?
- 我们可以这样理解,我们将a和b都看做是水平x轴上的一个点,
a%b
就表示我们从b点开始往后跳,每次跳的步长固定是b,一直跳到下一跳后的位置超过a停止,此时余数就是a减去当前位置,例如25%15
,15每次跳的步长就是15,此时它下一条是30超过了25,因此余数就是当前25-15=10 - 而
25%15
的时候,我们可以将每一跳的步长15看成是:步长为5每次必须跳3下,而5同时也是25的因子,因此25可以看成步长为5跳了5下,- 此时5是他们的公共跳跃因子,也就是说25一定在5的某一跳上,而15每次跳完也只可能是在5的某一跳上
- 那么此时当15的下一跳超过25的时候,他们中间的距离只可能是5的倍数,此时也就大大减少了映射空间
- 我们可以这样理解,我们将a和b都看做是水平x轴上的一个点,
- 而如果在
a%b
的时候b是个质数,那么a和b之间就没有公共跳跃因子,也就不会说他们的位置一定在一个因子的某一跳上,从而导致a%b
结果只可能是该因子的倍数