Give a one-line C expression to test whether an unsigned int is a power of two.
用一行c表达式检测一个无符号整数是否是2的幂(2的幂是指2的正整数次幂,比如4,8,16)
答案:
((n&(n-1))==0)
答案的原理是这样的:
2的幂的2进制形式是1后面跟着很多个0,如
100
10000
1000000
只要看见这样的数,立刻可以判定它是。
n和n-1是形如这样的二进制数:
01000000
00111111
可以看到,对应的位总是0和1都出现,所以,n&(n-1)一定是0
有同学可能想到用异或,n^(n-1)一定是全1。这个仔细想来就会发现不行,前面的补充零会导致前面有一些0。
现在已经看到,对2的幂进行n&(n-1)一定会是0,那么别的数一定会是非0吗?
随便举例:10010
10010 //原数
10001 //原数减一
10000 //按位与之后的结果
可以看到,确实是非0。
那么为什么呢?
只要一个二进制数是2的幂,减1就会造成位数减少一位。其他 任何数,都不会造成这种位数减少的现象。即,只有形如1000...0的形式的数字才会导致位数减少一位。因此n的第一个1(高位1)才会被减走,变成0,按位与的时候才会是0,否则最高位必是1,含1会造成整个表达式非0。