判断整数是否为2的幂次方最高效写法是n > 0 && (n & (n - 1)) == 0,因2的幂二进制仅含一个1,n & (n-1)可清最低位1,结果为0即满足;n>0排除0和负数误判。

判断一个整数是否为 2 的幂次方,最高效、最常用的实战写法就一行:n > 0 && (n & (n - 1)) == 0。它不依赖循环或递归,无分支预测开销,编译后通常只生成 2–3 条 CPU 指令,是图形计算、内存对齐、哈希索引等场景中的底层标配。
为什么必须加 n > 0?
2 的幂定义域仅限正整数(2⁰ = 1, 2¹ = 2, …),而位运算在边界值上极易失真:
- n == 0:0 & (-1) 中 -1 在补码下是全 1(如 32 位为 0xFFFFFFFF),结果非零,逻辑上误判;即使碰巧返回 false,也不代表条件可靠
- n :负数不在定义范围内,且补码运算使 n - 1 可能溢出(如 INT_MIN - 1 触发未定义行为)
- 单独用 (n & (n - 1)) == 0 会把 0 当作“满足”,但 0 不是 2 的幂
核心原理:二进制结构决定运算结果
所有正的 2 的幂,其二进制表示有且仅有一个 1:
- 1 → 0b1,1 - 1 = 0 → 0b0,0b1 & 0b0 = 0
- 8 → 0b1000,8 - 1 = 7 → 0b0111,0b1000 & 0b0111 = 0b0000
- 6 → 0b0110(非 2 的幂),6 - 1 = 5 → 0b0101,0b0110 & 0b0101 = 0b0100 ≠ 0
本质是 n & (n - 1) 清除 n 的最低位 1;若原数只有一个 1,清完即为 0;否则必残留至少一个 1。
其他位运算写法对比(不推荐主用)
虽存在替代形式,但实用性或可读性均不如主流写法:
- n > 0 && (n & (-n)) == n:利用补码中 -n 等价于 ~n + 1,n & (-n) 提取最低位的 1。若该值等于 n,说明只有这一个 1。逻辑等价,但理解成本更高
- n > 0 && (1073741824 % n == 0)(32 位下):用最大可表示的 2³⁰ 去模。依赖硬编码常量、不可移植,且模运算是重量级操作
实际编码注意事项
在 C/C++/Java 等语言中直接使用时需注意:
- 对 unsigned int 类型,可简化为
val && !(val & (val - 1)),因无符号类型天然排除负数 - 对 signed int,务必保留
n > 0,不能用n != 0替代 - 避免宏展开陷阱:如
#define IS_POWER_OF_TWO(n) ((n) > 0 && ((n) & ((n) - 1)) == 0),注意括号保护表达式 - 现代编译器(GCC/Clang/MSVC)对此模式识别极好,会自动内联并优化为无跳转指令序列










