Java中的Bitshifting
我试图理解位移是如何工作的。 有人可以解释一下这行的含义:
while ((n&1)==0) n >>= 1;
其中n
是一个整数,给出一个执行移位时n
的例子。
打破它:
n & 1
将在n和1之间进行二进制比较,即二进制为00000000000000000000000000000001。 因此,当n以1(正奇数或负偶数)结束时,它将返回0000000000000000000000000000000001,否则返回00000000000000000000000000000000。
如果n是偶数(或负奇数),则(n & 1) == 0
将为真,否则为假。
n >> = 1
相当于n = n >> 1
。 因此,它将所有位向右移动,这大致相当于除以2(向下舍入)。
如果例如n以12开始,那么在二进制中它将是1100.在一个循环之后它将是110(6),在另一个循环之后它将是11(3)然后循环将停止。
如果n为0,那么在下一个循环之后它仍然是0,并且循环将是无限的。
让n
为4
,二进制表示为:
00000000 00000000 00000000 00000100
(n&1)
按位, n
为1
。
1
具有以下二进制表示:
00000000 00000000 00000000 00000001
按位和的结果为0
:
00000000 00000000 00000000 00000100 = n 00000000 00000000 00000000 00000001 = 1 ------------------------------------ 00000000 00000000 00000000 00000000 = 0
所以条件是真实的。
有效地(n&1)
用于提取n
的最低有效位。
在while循环中,右移( >>
) n
乘以1
。 右移数字k
与将数字除以2^k
。
n
现在为00000000 00000000 00000000 00000100
右移一次变为00000000 00000000 00000000 00000010
即2
。
接下来,我们再次提取n的LSB(最低有效位),其为0
并且再次右移以给出00000000 00000000 00000000 0000001
,其为1
。
接下来我们再次提取n的LSB,现在为1
,循环中断。
因此,有效地将数字n
除以2
直到它变为奇数,因为奇数的LSB设置为奇数。
另请注意,如果n
开始为0
,则会进入无限循环,因为无论将0
除以2
您都不会得到奇数。
假设n = 12.这个位将是1100(1 * 8 + 1 * 4 + 0 * 2 + 0 * 1 = 12)。 第一次通过循环n&1 == 0,因为1100的最后一位是0,当你和那个1时,你得到0.所以n >> = 1将导致n从1100(12)变为110 (6)。 正如您可能注意到的那样,向右移动与除以2具有相同的效果。最后一位仍然为零,因此n和1仍将为0,因此它将再向右移动一次。 n >> = 1将使其向右移一位数到右边,从110(6)变为11(3)。
现在你可以看到最后一位是1,所以n&1将是1,导致while循环停止执行。 循环的目的似乎是将数字向右移动,直到找到第一个打开的位(直到结果为奇数)。
例如,如果n是
n= b11110000
然后
n&1= b11110000 & b00000001 --------- b00000000 n>>=1 b11110000 >> 1 --------- b01111000 n= b01111000
如果循环继续它应该是
n= b00001111
我们假设等于42
(仅仅因为):
int n = 42; while ((n & 1) == 0) { n >>= 1; }
迭代0:
-
n = 42
(或0000 0000 0000 0000 0000 0000 0010 1010
) -
n & 1 == 0
为true
(因为n&1 = 0或0000 0000 0000 0000 0000 0000 0000 0000
)
迭代1:
-
n = 21
(或0000 0000 0000 0000 0000 0000 0001 0101
) -
n & 1 == 0
为false
(因为n & 1 == 1
或0000 0000 0000 0000 0000 0000 0000 0001
)
它能做什么:
基本上,只要n是偶数,你就将n除以2:
- n&1是一个简单的奇偶校验,
- n >> = 1将位移到右边,它除以2。
n&1实际上是一个按位AND操作。 这里n的位模式将与1的位模式进行ANDED。谁的结果将与零进行比较。 如果是,则n右移1次。 您可以将右移一个除以2,依此类推。