递增 'masked' 位集

Incrementing 'masked' bitsets

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

我正在查看掩码位集,即设置位是掩码子集的位集,即 0000101 和掩码 1010101。我想要完成的是增加位集,但仅限于屏蔽位。在此示例中,结果将是 0010000。为了让它更清楚一点,只提取掩码位,即 0011,将它们递增到 0100 并再次将它们分配给掩码位,得到 0010000.

除了使用位扫描和前缀掩码的组合手动执行操作之外,是否有人看到了执行此操作的有效方法?

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

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

虽然与公认的答案相比不够直观,但只需 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

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

如果迭代的顺序不是那么重要,一个自减操作就可以满足你的需要,可以只用两个操作:

让我们从

开始

x = mask

并使用

获取之前的值

x = (x - 1) & mask

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