我试图了解位移的工作原理。有人可以解释这一行的含义:
while ((n&1)==0) n >>= 1;
其中n
是一个整数,并在执行班次时给我一个n
的例子。
答案 0 :(得分:15)
打破它:
n & 1
将在n和1之间进行二进制比较,其中二进制为00000000000000000000000000000001
。因此,当n以1(正奇数或负偶数)结束时,它将返回00000000000000000000000000000001
,否则将返回00000000000000000000000000000000
。
(n & 1) == 0
将为真,否则为假。
n >> = 1
相当于n = n >> 1
。因此,它将所有位向右移动,这大致相当于除以2(向下舍入)。
如果是n以12开始,然后是二进制,它将是1100.在一个循环之后它将是110(6),接着是11(3)然后循环将停止。
如果n为0,那么在下一个循环之后它仍然是0,并且循环将是无限的。
答案 1 :(得分:8)
让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
所以while的条件是真的。
有效(n&1)
用于提取n
的最低有效位。
在while循环中右移(>>
)n
1
。将数字右移k
与将数字除以2^k
相同。
n
正在转移的 00000000 00000000 00000000 00000100
变为
00000000 00000000 00000000 00000010
2
。
接下来,我们再次提取n
的{{1}}的{LS}(最低有效位),再次右移以提供0
00000000 00000000 00000000 0000001
。
接下来我们再次提取n的LSB,现在是1
并且循环中断。
因此,您可以有效地将您的号码1
除以n
,直到它变为奇数,因为奇数号已经设置了LSB。
另请注意,如果2
开始为n
,您将进入无限循环,因为无论您将0
划分为0
多少次?不会得到奇数。
答案 2 :(得分:4)
假设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将使其向右移一位数到右边将n从110(6)改为11(3)。
现在你可以看到最后一位是1,所以n& 1将为1,导致while循环停止执行。循环的目的似乎是将数字向右移动,直到找到第一个打开的位(直到结果为奇数)。
答案 3 :(得分:1)
例如,如果n是
n= b11110000
然后
n&1= b11110000 &
b00000001
---------
b00000000
n>>=1 b11110000 >> 1
---------
b01111000
n= b01111000
如果循环继续,它应该是
n= b00001111
答案 4 :(得分:1)
我们假设等于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:
答案 5 :(得分:0)
n& 1实际上是一个按位AND操作。这里n的位模式将与1的位模式进行AND运算。谁的结果将与零进行比较。如果是,则n右移1次。您可以将右移一分为2,依此类推。