表达式 "x & (x + (1 << n))" 是如何工作的?
How does the expression "x & (x + (1 << n))" work?
我正在阅读的文字是这样说的:
x & (x + (1 << n)) = x, with the run of set bits (possibly length 0) starting at bit n cleared.
我尝试在 python 控制台中输入不同的值并看到:
>>> 5 & (5 + (1 << 2))
1
但是,当我尝试输入其他不同的值而不是 2 时,我得到了 5 作为答案。我尝试输入 1 到 7 之间的值。
我试着推导出表达式,但我做不到。
对此必须有什么合理的解释?它是如何工作的?
I tried putting in values from 1 to 7 [for n]
n = 0
也可以。其实我们先来看那个案例。所以 x & (x + 1)
.
如果x
是奇数,那么x
的形式是a01k(有些bit-stringa
,后面跟着一个零,然后是 k
个)。给它加 1 会带走所有尾随的,把它变成 a10k。 And-ing x
用新的尾随零取消旧的尾随,并且与旧 0 一起出现的新 1。a
保持不变。换句话说:尾随的被重置了。
如果x
是偶数,那么加1不进位,唯一的作用就是最低有效位被置位。与 x
的 AND 然后再次重置该位。总的来说什么都没发生。
如果 n
不为零,则好像 n
最低有效位不存在。添加不会影响它们,因此 AND 也不会。所以总的来说,x & (x + (1 << n))
可以描述为“如果有一个 运行 从位置 n
开始,将 运行 清零,否则什么都不做”。
一个可能有趣的变体是 x & (x + (x & -x))
,它首先使用 x & -x
来获得最低有效设置位的掩码,然后与原始表达式相同。那会找到第一个 运行 并重置它。
我正在阅读的文字是这样说的:
x & (x + (1 << n)) = x, with the run of set bits (possibly length 0) starting at bit n cleared.
我尝试在 python 控制台中输入不同的值并看到:
>>> 5 & (5 + (1 << 2))
1
但是,当我尝试输入其他不同的值而不是 2 时,我得到了 5 作为答案。我尝试输入 1 到 7 之间的值。
我试着推导出表达式,但我做不到。
对此必须有什么合理的解释?它是如何工作的?
I tried putting in values from 1 to 7 [for n]
n = 0
也可以。其实我们先来看那个案例。所以 x & (x + 1)
.
如果x
是奇数,那么x
的形式是a01k(有些bit-stringa
,后面跟着一个零,然后是 k
个)。给它加 1 会带走所有尾随的,把它变成 a10k。 And-ing x
用新的尾随零取消旧的尾随,并且与旧 0 一起出现的新 1。a
保持不变。换句话说:尾随的被重置了。
如果x
是偶数,那么加1不进位,唯一的作用就是最低有效位被置位。与 x
的 AND 然后再次重置该位。总的来说什么都没发生。
如果 n
不为零,则好像 n
最低有效位不存在。添加不会影响它们,因此 AND 也不会。所以总的来说,x & (x + (1 << n))
可以描述为“如果有一个 运行 从位置 n
开始,将 运行 清零,否则什么都不做”。
一个可能有趣的变体是 x & (x + (x & -x))
,它首先使用 x & -x
来获得最低有效设置位的掩码,然后与原始表达式相同。那会找到第一个 运行 并重置它。