我一直在通过Kernighan和Ritchie“C编程语言”进行处理并阅读x mod y == x & y-1
。所以,我用铅笔和纸做了它,工作得很好,所以我试着测试它,这就是问题所在:
代码:
#include <stdio.h>
main()
{
int i, j;
for(i = 1; i < 10; i++){
for(j = 1; j < 10; j++)
printf("%3d",i & j-1);
printf("\n");
}
}
给出输出:
0 1 0 1 0 1 0 1 0
0 0 2 2 0 0 2 2 0
0 1 2 3 0 1 2 3 0
0 0 0 0 4 4 4 4 0
0 1 0 1 4 5 4 5 0
0 0 2 2 4 4 6 6 0
0 1 2 3 4 5 6 7 0
0 0 0 0 0 0 0 0 8
0 1 0 1 0 1 0 1 8
和
#include <stdio.h>
main()
{
int i, j;
for(i = 1; i < 10; i++){
for(j = 1; j < 10; j++)
printf("%3d",i % j);
printf("\n");
}
}
给出输出:
0 1 1 1 1 1 1 1 1
0 0 2 2 2 2 2 2 2
0 1 0 3 3 3 3 3 3
0 0 1 0 4 4 4 4 4
0 1 2 1 0 5 5 5 5
0 0 0 2 1 0 6 6 6
0 1 1 3 2 1 0 7 7
0 0 2 0 3 2 1 0 8
0 1 0 1 4 3 2 1 0
请注意,唯一的变化是成为%
的{{1}}。
任何意见都将非常感激
答案 0 :(得分:6)
等式
x mod y == x & y-1
仅正确y
2的幂。
如果y = 2^k
,y
的二进制表示是一位1位后跟k
0位(并且前面有一些0位,具体取决于宽度)类型),y-1
的表示形式是k
1位(前面带有0)。
然后,如果您使用x = q*y + r
编写0 <= r < y
,则r
的二进制表示最多需要k
位,k
位最后q*y
位x
1}}都是0,因此y
modulo k
的余数由x
的最低有效y-1
位组成,这些位由按位和{{{}}获得1}}。
对于奇数y > 1
,y-1
是偶数,因此x & y-1
始终是偶数,因此(y+1) % y == 1 != (y+1) & (y-1)
。对于偶数y
而不是2的幂,将1替换为2,对应y
中y+1
的最低设置位。