下面的代码返回给定数字是否为2的幂。它是如何工作的?

时间:2015-08-29 12:26:01

标签: java bitwise-operators

我可以理解它使用逐位AND运算符,但它是如何工作的?

Emgu.CV.dll

3 个答案:

答案 0 :(得分:6)

如果num是2的幂,num & (num1 -1)为0,因为num-1将有1位,num有0位,0位有num有1位。

如果num是2的幂,则它有一个1位:

num           00..00100000000..00
num-1         00..00011111111..11
num & (num-1) 00..00000000000..00

如果num不是2的幂,则num中至少有两个1位。如果你检查它们中的第一个和最后一个,你得到:

num           00..001xx..xxx10..0
num-1         00.0001xx..xxx01..1
num & (num-1) 00.0001xx..xxx00..0

因此num & (num-1)至少有一个1位。

答案 1 :(得分:1)

两个人的权力总是只有一个“1”:

20 = 1 → 0000 0001
21 = 2 → 0000 0010
22 = 4 → 0000 0100
23 = 8 → 0000 1000

......等等。

任何其他数字至少有两个“1”位。例如,数字6是0110,数字9是1001,依此类推。

当你从一个数字中减去一个时,要么你在最右边的位置有一个:

 00000101
-00000001
 ────────
 00000100

或者您需要从左边的另一个借来。

 00010100
-00000001
 ────────
 00010011

这意味着有效地,右边的第一个“1”不在结果中,右边的所有数字都将变为“1”。左边的所有数字都没有改变。

因此,如果初始数字中只有一个“1” - 它是2的幂 - 那么我们将在0所在的位置为0。使用&,您得到的是:

23 = 8 → 0000 1000
    -1 → 0000 0111
    &8 → 0000 0000

原始8中零的所有位在&之后将为零。我们知道减去第一个“1”的位置为零。所以在&之后也会变为零。结果:整数为零。

但是如果数字 2的幂,则在减法借用的那个数字的左边有另一个“1”位。那个“1”位不会改变:

 24 → 0001 1000
 -1 → 0001 0111
&24 → 0001 0000

右侧,一直到第一个原始“1”现在为零。但正如我们注意到的那样,第一个“1”左边的位没有改变,它们没有被借用。因此,当您对左侧的位执行&时,结果中仍会显示“1”。

所以这种情况下的结果不会为零。

因此,当您执行n & (n-1)时,如果n不是2的幂,则您将拥有多个“1”位,结果为非零。如果它是2的幂,你只有一个“1”位,结果将为零。

答案 2 :(得分:0)

所有关于整数值的二进制表示的性质。

在每个位置符号中,相同的符号用于不同的数量级。在二进制表示中,符号1用于2的大小,具体取决于其位置。这样,任何整数都可以表示为2的幂之和:

5 10 = 101 2 = 1 * 2 2 + 0 * 2 1 + 1 * 2 0

不难看出,为了表示2的力量,在相应的位置只需要1的一个符号。所以代码:

num1 & (num1 - 1)

只是检查在值的二进制表示中只有1位设置为1