一行c表达式检测无符号整数是否是2的幂

来源:互联网 发布:linux jstack命令 编辑:程序博客网 时间:2024/05/21 17:06

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。