如何使用逐位运算实现位向量

How to implement bit vectors with bitwise operations?

本文关键字:实现 向量 运算 何使用      更新时间:2023-10-16

我正在研究《编程珍珠》一书中的一个问题,他们建议用这个函数来设置位向量中的一位。我对它的作用有点困惑。

#define BITSPERWORD 32
#define MASK 0x1F
#define SHIFT 5
#define N 1000000
int a[1 + N/BITSPERWORD];
void set(int i){
   a[i >> SHIFT] |= (1 << (i & MASK)); 
}

以下是我对该代码的(可能是错误的)解释。如果i=64,

1) 首先,它取i并将其向右移位SHIFT(即5)位。这相当于DIVIDING(不是像我最初想的那样)i乘以2^5。因此,如果i64,则a的索引是2 (64 / 2^5)

2) a[2] |= (1 << (64 & MASK))
64 & 1 = 1000000 & 01 = 1000001
所以1被左移了多少位????

  1. 这个方法似乎是如何工作的,尽管我觉得有更好的方法可以设置一点。是为了找到ith比特的索引,它本质上除以32,因为这是每个字的比特数
  2. 由于此处使用的运算符是|,因此功能是将位设置为1,而不是切换位
  3. 0x1F实际上是31,当与i相加时,得到余数(不确定他们为什么不使用%
  4. 最后,移位将1带到正确的位置,或者它与向量中的右槽对齐

如果您计划使用此代码

  1. 你可以在没有定义的情况下写得很清楚,使用更明显的方法,我怀疑这会在速度上有所不同
  2. 此外,您可能只应该使用std::bitset
  3. 使用掩码来获取剩余值特别让我恼火,因为我很确定它不一定对每个数字都有效,31恰好有效,因为它都是1