我目前正在编写树枚举器的过程中遇到以下问题:
我正在查看被屏蔽的位集,即设置的位是掩码的子集的位集,即0000101
具有mask的位集1010101
。我要完成的是增加位集,但仅是相对于掩码位。在此示例中,结果将为0010000
。为了使其更清晰,仅提取被屏蔽的位,即0011
,将它们增加到0100
并再次将它们分配给屏蔽位,得到0010000
。
除了使用bitcans和前缀掩码的组合手动执行操作之外,有人能看到实现此目的的有效方法吗?
我目前正在编写树枚举器的过程中遇到以下问题:
我正在查看被屏蔽的位集,即设置的位是掩码的子集的位集,即0000101
具有mask的位集1010101
。我要完成的是增加位集,但仅是相对于掩码位。在此示例中,结果将为0010000
。为了使其更清晰,仅提取被屏蔽的位,即0011
,将它们增加到0100
并再次将它们分配给屏蔽位,得到0010000
。
除了使用bitcans和前缀掩码的组合手动执行操作之外,有人能看到实现此目的的有效方法吗?
Answers:
只需在非掩码位中填充1,以便它们传播进位:
// increments x on bits belonging to mask
x = ((x | ~mask) + 1) & mask;
x
。可能的x = (x & ~mask) | (((x | ~mask) + 1) & mask);
。
0101101
(例如.1.1.0.
,在非掩码位和0.0.1.1
“计数器”中),则它们将是需要的 0111000
(0.1.0.0
保留时的新“计数器” .1.1.0.
)还是0010000
可接受的。这个答案(可能还有其他答案,尽管我没有检查过)给了后者。如果需要,我的版本应该提供前者。
与接受的答案相比,虽然不直观,但仅需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 | ~mask) + 1
只要您证明只要x是mask的子集,然后引用我的答案,您的验证就会简单得多。
-(x^mask) == ~((x ^ mask) - 1) == ~(x ^ mask) + 1 == (x ^ ~mask) + 1 == (x | ~mask) + 1
。最后一个方程式成立是因为位集是不相交的,其他位集始终为真(至少在2补码中)。