2配方的力量帮助

时间:2011-02-22 18:35:34

标签: java math binary

我理解Java中的(2 * i ==(i ^(i - 1)+ 1)会让我发现一个数字是2的幂。但有人可以解释为什么这有效吗?

2 个答案:

答案 0 :(得分:14)

2 * i ==(i ^(i-1))+ 1

基本上,如果i是2的幂,它的位模式将只有一个1。如果从中减去1,则1位的所有低位变为1,并且该2位幂将变为0.然后对位执行XOR ,产生全1位模式。你加1,你得到下一个2的幂。

记住异或真值表:

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位模式。

答案 1 :(得分:0)

重要的一点是i ^(i-1)(我假设这是问题中的一个小错字)。假设i是2的幂。那么它的二进制扩展是1,后跟很多零。 i-1是一个数字,其中前导1被零替换,所有的零被1替换。因此,XOR的结果是1的字符串,与i的位数相同。

另一方面,如果i不是2的幂,则从中减去1将不会翻转所有这些位 - 然后xor会在您减去时识别哪些位从一个位置传送到下一个位置1. xor的结果将为零,因此当您添加1时,它将不会进入下一位位置。