判断4的幂需同时满足三个条件:x > 0、(x & (x - 1)) == 0(是2的幂)、(x & 0x55555555) != 0(唯一1在偶数位),缺一不可。

判断4的幂需要同时满足两个条件
一个数是4的幂,等价于它是2的偶数次幂(即 4^n = 2^(2n))。所以不能只看是否为2的幂,还要确认指数是偶数。常见错误是只用 (x & (x - 1)) == 0 判断2的幂,但这样会把2、8、32等非4的幂也判为真。
正确思路分两步:先确保是2的幂(仅一个bit为1),再确保那个1落在偶数位上(bit位置从0开始计数:0、2、4、6…)。
用 (x & (x - 1)) == 0 排除非2的幂
这是经典技巧:对正整数 x,x & (x - 1) 清除最低位的1;结果为0说明原数只有1个bit为1 —— 即是2的幂(包括1、2、4、8…)。
- 必须加
x > 0判断,否则x = 0或负数会误判 -
x = 1是4^0,合法,该式返回 true -
x = 2→2 & 1 == 0,也通过,需后续过滤
用掩码 0x55555555 检查1是否在偶数位
32位下,4的幂对应的bit位置是0、2、4、…、30,二进制表示为 0101 0101 0101 0101 0101 0101 0101 0101,即十六进制 0x55555555。与这个掩码做按位与,结果等于自身,说明唯一的1落在这些位置上。
完整判断表达式:
bool isPowerOfFour(int x) {
return x > 0 && (x & (x - 1)) == 0 && (x & 0x55555555) != 0;
}
-
0x55555555是32位安全掩码;若目标平台是64位,可用0x5555555555555555ULL - 不要用
(x & 0x55555555) == x—— 当x == 0时也成立,但前面已有x > 0保证,所以!= 0更直接 - 该掩码法比模3判断(利用
4^n % 3 == 1)更快,无除法开销
为什么不用 x % 3 == 1?
数学上确实有性质:所有4的幂模3余1,且所有2的幂中只有4的幂满足这点。但实际使用要注意:
- 编译器不一定能把
% 3优化成位运算,尤其在未开启O2时可能生成除指令 - 负数取模行为依赖实现,而
x > 0已限定范围,位运算路径更可控 - 掩码法一次AND+一次SUB+一次AND,三步纯位操作,延迟更低
真正容易被忽略的是:必须同时检查正数性、2的幂性、位位置——少任何一个条件都会漏判或误判。比如 x = 16 过三关,x = 8 卡在掩码检查(8 & 0x55555555 == 0),x = 0 卡在第一步。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











