增加'蒙面'位集

时间:2017-06-26 19:14:48

标签: c++ c bit-manipulation intrinsics

我目前正在编写一个树枚举器,我遇到了以下问题:

我正在研究掩蔽的位集,即设置位是掩码的子集的位集,即具有掩码0000101的{​​{1}}。我想要完成的是增加位集,但仅限于屏蔽位。在此示例中,结果为1010101。为了使它更清晰一点,只提取掩码位,即0010000,将它们递增到0011并再次将它们分配到掩码位,得到0100

有没有人看到一种有效的方法来做到这一点,没有使用bitcans和前缀掩码的组合手动实现操作?

3 个答案:

答案 0 :(得分:120)

只需将非掩码位填充为1,以便它们传播进位:

// increments x on bits belonging to mask
x = ((x | ~mask) + 1) & mask;

答案 1 :(得分:19)

虽然与接受的答案相比并不直观,但这只需3个步骤:

x = -(x ^ mask) & mask;

这可以按照zch:

的建议进行验证
  -(x ^ mask)
= ~(x ^ mask) + 1  // assuming 2's complement
= (x ^ ~mask) + 1
= (x | ~mask) + 1  // since x and ~mask have disjoint set bits

然后它就等同于接受的答案。

答案 2 :(得分:7)

如果迭代次序不那么重要,并且减量操作将满足您的需要,则可以只使用两个操作:

让我们从

开始

x = mask

并使用

获取上一个值

x = (x - 1) & mask

x - 1部分将最后一个非零位更改为零,并将所有不太重要的位设置为1。然后& mask部分只留下掩码位。