求一个int数是否是4的幂

来源:互联网 发布:贵州云博大数据 编辑:程序博客网 时间:2024/06/02 19:33

在LeetCode上看到一篇关于求一个int数是否是4的幂的算法,觉得十分巧妙,觉得有必要记一下。


我们来看看二进制对应位上的十进制是多大:

 1       1     1     1              1      1      1      1

2^7  2^6  2^5  2^4          2^3  2^2  2^1  2^0



二进制每一位上的十进制值都是2的幂。其中指数是偶数的话就是4的幂了。比如:2^0 = 2^(2 * 0) = 4^0,   2^2 = 2^(2*1) = 4^1,  2^4 = 2^(2*2) = 4^1,2^6=2^(2*3) = 4*4,

所以4的幂的数的二进制表示就是在奇数位上有个1(因为最低为从0开始)。在这里的情况就是:0000 0001,0000 0100,0001 0000,0100 0000.


我们可以看到4的幂都是只有一个1,其他位都是0。如何判断一个数n二进制上只有一个1?我们可以让这个数n和n-1进行按位与操作,如果结果是0就说明n是个二进制表示只有一个1的数,非0就说明n不止一个1。为什么n & (n - 1)能有这种作用呢?下面我来解释一下。

n - 1它的二进制表示就是n的最低位上的1变成0,后面的0都变成1,这个最低位1的前面的位都和以前保持不变,因为你进行减1操作,如果最低位的值=1(这里只能等于1,因为是二进制。=1表示最低位的值足够进行减1操作),最低位减1后变成0(这里已经没有更后面的位了,所以也符合最低位的1变成0,后面的0都变成1)。如果最低位为0,(不够被1减),它就会向前借,知道碰到1。所以这个最低位被借后变成0,后面的0都变成1(被1减后)。文字表述看起来补直观,下面看几个具体的例子:



0101 1000 - 0000 0001 = 0101 0111

0001 0000 - 0000 0001 = 0000 1111

0000 0001 - 0000 0001 = 0000 0000


所以n - 1的作用就是从n的最低位(包含这个位,我们说这个位置为L)的1开始一直向后的二进制位取反,比L位高的二进制位不变。n & (n - 1)的结果的二进制就会是这样的。

L位和低于L位全为0(值为0)。高于L的位和原来一致(因为n 和 n - 1在这一部分没变化,相当于自己和自己按位与)。如果只有L位是1,其他位都为0,那么比L高的位按位与后也为0,就是说n & (n - 1)== 0。不为0,说明比L位高的位还有1,表示二进制位上不止一个1。


我们用n & (n - 1)== 0找到了二进制表示有且只有一个1的数。这样的数不全是4的幂,4的幂应该是奇数位上有个1,所以我们把那些偶数位上为1的给排除掉。

n & (10101010 10101010 10101010 10101010)  == 0这样就排除了偶数位上的1的数。


所以如果一个int型的数n满足下面这个条件就是4的幂

(n & (n - 1) == 0) && (n & 0xAAAAAAAA == 0)



0 0
原创粉丝点击