今天一个小伙伴说在一个算法里面看到代码
x&=(x-1)
不明白它的意思,于是我给ta分析了一下,在此分享出来,其实也很好理解,想清就行了。
理解x&=(x-1):
-
单纯的去看这些位运算的话,如果不是接触很多,很难一眼看出它的含义,我们不妨拿几个数先试试,理解一下它的实际运算过程,这样就很好理解了。
- 假设x=3,也就是
11
。 - 那么x-1=2,也就是
10
。 - 那么此时
x&(x-1)
也就等于11&10
,根据&
的运算规则,相同为1
,不同为0
,那么运算结果是10
。
- 假设x=3,也就是
-
有了上面这个例子,我们大概知道式怎么计算的了。然后我们再从宏观的角度去理解一下,这里我们就有一个问题了,二进制里面
x-1
是怎么算的?- 假设
x
二进制位的最后一位是1
,那么它减去1后应该是0
,变化的只有这一位,那么它再与原来的数相与的话,就是把最后一位由1变成了0。 - 假设
x
二进制位的最后一位是0
,那么它减1的结果就取决于它的上一位,如果它的上一位还是0
,那么还要继续往上找,直到某一位是1
为止,减完后,整个数的变化是:这个二进制的最后一个1变成了0,之后的数都变成了1。 那么这个数再与原来那个数相与,变化是:只把最后一个1变成了0。
- 假设
-
综上所述,
x&=(x-1)
的含义是:将 xx 的二进制表示的最后一个 1 变成 0 。 -
我们也可以利用这个性质统计出某个二进制数里面1的个数,也就是不断的进行
x&=(x-1)
操作,直到x
为0
为止,其中操作次数就是这个二进制数里面1的个数。
int count(int x){
int res=0;
while(x>0){
x&=(x-1);
res++;
}
return res;
}
- 这里仅把这个位运算的含义弄清楚,其它的就不多做拓展了。