我今天开始阅读"Programming Pearls",在做练习的时候,我遇到了这个问题"你如何实现你自己的位向量?"。当我看到解决方案时,它是这样的:
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];
void set(int i) { a[i >> SHIFT] |= (1 << (i & MASK));
我感到困惑的地方是这个语句
1 << (i & MASK)
谁能给我解释一下这是怎么回事? 注意,MASK
的设置使得它具有最低的SHIFT
位集,其中SHIFT
恰好是BITSPERWORD
的以2为底的对数。
因此,(i & MASK)
将选择i
的最低5位,这与除32后取余数相同(例如,只需考虑如何取十进制数的最低两位数除以100后得到余数)。这就是我们感兴趣的中位的个数。
1 << (i & MASK))
(顺便说一下,这是一个表达式,而不是语句)现在创建的值恰好是我们感兴趣的位。将此值与|=
合并到内存字中,将设置位向量的所需位。
0x20是32,所以i & 0x1F
取i
对32取模,所以你永远不会移位32位。这是一种保护措施,因为移位任何不严格小于类型大小的东西都是未定义的行为。