这里使用的第一个简单事实是,如果我们取值7(二进制中的111)并开始重复递减它(一直到0),我们将通过二进制表示
111, 110, 101, 100, 011, 010, 001, 000
它以一种相当明显的方式表示原始 3 集的所有可能子集。
第二个事实是,在二进制中“减少x”(“从x 中减去1”)意味着:将x 的所有位从最不重要(最右边)的一位开始反转到留到(包括)x 表示中的第一个 1。 “向左”在这里的意思是“在增加位重要性的方向上”。
例如
00001000 - 1 = 00000111, i.e. we invert the `1000` tail
01010101 - 1 = 01010100, i.e. we invert just the `1` tail
10000000 - 1 = 01111111, i.e. we invert the whole thing
and so on
递减操作“关闭”二进制表示中最低有效的1 位并“打开”它右侧的所有零位。
现在,第三个事实是,在您的情况下,x 的1 位始终是y 的1 位的子集,因为我们从x = y 开始并在每次迭代中执行x = (whatever) & y .
当我们执行x - 1 时,我们“关闭”(设置为0)x 中的最低1 和“打开”(设置为1)所有0 中的x从最低的1 向右。
当我们在 x = (x - 1) & y 中使用 & y 时,我们“关闭”一些 原始位 x 中的 y 并“打开” x 中 y 的所有低 原始 位。
此时应该已经很明显了,该操作只是x 的“掩码递减”:通过执行x = (x - 1) & y,我们只需递减x 的值,假设只有被@987654355 掩码的位@ 形成x 的值,而所有其他位只是可忽略的“填充位”。
为了与上面的例子相似,递减7,y 的初始值可能看起来像10010100。操作x = (x - 1) & y 会将此值视为某种“分布式 7”(非正式地说)。 x 将通过以下值进行处理
1..1.1.., 1..1.0.., 1..0.1.., 1..0.0.., 0..1.1.., 0..1.0.., 0..0.1.., 0..0.0..
其中. 表示x 的“填充”位,它们并不真正参与这个“掩码减量”操作(实际上它们将是0)。注意与原始示例的相似之处7.