这是面试中问到的问题。可以先分析一下2的n次幂形式的数,其二进制形式必然是只有1bit是1,其余bit位都是0
因此一个直观的做法就是跟所有2的n次幂比较,由于我们通常考虑的无符号整型是32位,因此就有32个2的n次幂的数(可以通过将1左移0到31位得到)。这种方法在最坏情况下需要移位并比较32次,效率比较低。
再仔细分析一下可以发现,2的n次幂形式的数,其二进制形式为0...010...0,假设1后面有i个0 (0<=i<=31),则这个数减去1就会出现一个末尾连续i个1的数。例如二进制数0100,这个数减去1等于0011,这两个数的与为0
因此,一个更优的算法是:
inline
bool
is2n(unsigned
int
i)
{
if(i==0) return false;
else return (i&(i-1))==0;
}
因此一个直观的做法就是跟所有2的n次幂比较,由于我们通常考虑的无符号整型是32位,因此就有32个2的n次幂的数(可以通过将1左移0到31位得到)。这种方法在最坏情况下需要移位并比较32次,效率比较低。
再仔细分析一下可以发现,2的n次幂形式的数,其二进制形式为0...010...0,假设1后面有i个0 (0<=i<=31),则这个数减去1就会出现一个末尾连续i个1的数。例如二进制数0100,这个数减去1等于0011,这两个数的与为0
因此,一个更优的算法是:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)