我可以理解它使用逐位AND运算符,但它是如何工作的?
Emgu.CV.dll
答案 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
。