我知道Java中的(2 * i ==(i ^(i-1)+ 1)会让我发现数字是否为2的幂,但是有人可以解释为什么这行得通吗?
最佳答案
2 * i ==(i ^(i-1))+ 1
基本上,如果i
为2的幂,则其位模式中将只有一个1
。如果从中减去1,那么1
位的所有低位将变为1
,并且该2的幂将变为0。然后对这些位执行XOR
,将产生一个全1的位模式。将1加到下,得到2的下一个幂。
记住XOR真值表:
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
例子:
假设
i
是256,这就是这种位模式。100000000 = 2^8 = 256
100000000 - 1 = 011111111 = 2^7 + 2^6 + ... + 2^0 = 255
100000000 ^ 011111111 = 111111111 = = 2^8 + 2^7 + ... + 2^0 = 511
111111111 + 1 = 1000000000 = 2^9 = 512 = 2*i
这是一个示例,当您没有获得2的幂时
i = 100 = 2^6 + 2^5 + 2^2
0110 0100
0110 0100 - 1 = 99 = 2^6 + 2^5 + 2^1 + 2^0 = 0110 0011
0110 0100 ^ 0110 0011 = 0000 0111 = 2^2 + 2^1 + 2^0 = 7
0000 0111 + 1 = 000 1000 = 2^3 = 8 != (2*i)
简化版
另外,此检查有一个修改后的版本,用于确定某个正无符号整数是否为2的幂。
(i & (i-1)) == 0
基本上,相同的理由
如果
i
是2的幂,则它的位表示中只有一个1
位。如果从中减去1,则1
位变为0,所有低位变为1
。然后AND
将产生所有0
位模式。