为什么如果 (n & -n) == n 那么 n 是 2 的幂?
2022-08-31 12:06:18
因为在 2 的补码中,是 。-n
~n+1
如果 是 2 的幂,则它只设置了一个位。因此,除了那一个之外,所有位都设置好了。添加 1,然后再次设置特殊位,确保等于 。n
~n
n & (that thing)
n
反之亦然,因为 0 和负数被该 Java 源中的前一行排除。如果设置了多个位,则其中一个是最高的此类位。这个位不会被 设置,因为有一个较低的清除位来“吸收”它:n
+1
n: 00001001000
~n: 11110110111
-n: 11110111000 // the first 0 bit "absorbed" the +1
^
|
(n & -n) fails to equal n at this bit.
描述并不完全准确,因为 0 不是 2 的幂。更好的说法是(0 & -0) == 0
((n & -n) == n)
当 n 是 2 的幂,或 2 的幂的负数,或零。
如果 n 是 2 的幂,则二进制中的 n 是单个 1 后跟零。二进制补数中的 -n 是逆 + 1,因此位排列在一起
n 0000100...000
-n 1111100...000
n & -n 0000100...000
要了解为什么这有效,请考虑二的补码为逆+ 1,-n == ~n + 1
n 0000100...000
inverse n 1111011...111
+ 1
two's comp 1111100...000
因为当你在添加一个以获得两个的补充时,你一直带着一个。
如果 n 不是 2 的幂†那么结果会丢失一点,因为由于该携带,两者的补码不会设置最高位。
† - 或零或二次幂的负数...如顶部所述。