【问题标题】:How to implement bit vectors with bitwise operations?如何通过按位运算实现位向量?
【发布时间】:2013-07-20 16:57:44
【问题描述】:

我正在研究《Programming Pearls》一书中的一个问题,他们推荐使用此函数在位向量中设置位。我对它的作用有点困惑。

#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)位。这相当于将i2^5 相除(而不是相乘)。所以如果i64,那么a的索引就是2(64 / 2^5)

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

【问题讨论】:

  • 右移是除以二。
  • This is equivalent to multiplying i by 2^5. NO 这相当于i除以2^5
  • 你确定iint 不是unsigned int 你从哪里得到这个代码?
  • 糟糕。好的,所以我将其更改为反映除以 2^5。剩下的呢?
  • 2 (64 / 2^5) ?或者只有(64 / 2^5) ...想想,如果1000 &gt;&gt; 1 == 0100 所以x &gt;&gt; 5 == x / 2^5 只有

标签: c++ c bit-manipulation bitwise-operators


【解决方案1】:
  1. 看起来这种方法是如何工作的,尽管我觉得有更好的方法来设置一点。是找到ith 位的索引,它基本上除以32,因为这是每个字的位数。
  2. 由于此处使用的运算符是|,因此该函数将位设置为不切换位的位
  3. 0x1F 实际上是 31,当与 i 进行与运算时,你会得到余数(不知道他们为什么不使用 %
  4. 最后,移位将 1 带到正确的位置,或者将它与向量中的正确槽位对齐。

如果您打算使用此代码

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

【讨论】:

  • +1 用于澄清 0X1F 是 31 .. 我一直认为它是 1。哇。这清楚了很多。谢谢。
  • @HenleyChiu lol 没问题,老实说有更清晰的设置方法,我不喜欢这段代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
相关资源
最近更新 更多