C - 简单模数表的麻烦,它不是那么简单

时间:2012-10-28 20:43:06

标签: c bit-manipulation modulus

我一直在通过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}}。 任何意见都将非常感激

1 个答案:

答案 0 :(得分:6)

等式

x mod y == x & y-1

正确y 2的幂。

如果y = 2^ky的二进制表示是一位1位后跟k 0位(并且前面有一些0位,具体取决于宽度)类型),y-1的表示形式是k 1位(前面带有0)。

然后,如果您使用x = q*y + r编写0 <= r < y,则r的二进制表示最多需要k位,k位最后q*yx 1}}都是0,因此y modulo k的余数由x的最低有效y-1位组成,这些位由按位和{{{}}获得1}}。

对于奇数y > 1y-1是偶数,因此x & y-1始终是偶数,因此(y+1) % y == 1 != (y+1) & (y-1)。对于偶数y而不是2的幂,将1替换为2,对应yy+1的最低设置位。