2配方的力量帮助

据我所知(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的下一个幂。

记住异或真值表:

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

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

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