<p>(n & (n - 1)) == 0 且 n > 0 可高效判断正整数是否为2的幂,原理是2的幂二进制仅含一个1,n-1将其变为0并右置全1,按位与得0;需排除0和负数,其他等效方法包括 n & (-n) == n 和 Integer.bitCount(n) == 1。</p>

直接用 (n & (n - 1)) == 0 配合 n > 0 就能高效判断——这是最常用也最巧妙的位运算解法,时间复杂度 O(1),无需循环或对数计算。
核心原理:二进制中只有一个 1
2 的整数次幂(如 1、2、4、8、16…)在二进制下都形如 1 后跟若干个 0:
1 → 1
2 → 10
4 → 100
8 → 1000
而 n−1 正好把那个唯一的 1 变成 0,并将其右边所有 0 全变成 1。
所以 n & (n−1) 必然为 0。
- 例如 n = 8(1000),n−1 = 7(0111),1000 & 0111 = 0000
- 再如 n = 1(1),n−1 = 0(0),1 & 0 = 0
必须加 n > 0 判断
这个技巧只对正整数成立,0 和负数会出错:
- n = 0:0 & (−1) 在 Java 中结果是 −1(补码全 1),不为 0,但 0 不是 2 的幂
- n :负数二进制不是纯幂结构,且 n−1 更小,逻辑无意义
所以完整表达式一定是:n > 0 && (n & (n - 1)) == 0
其他位运算方法作为补充
除了主流的 n & (n−1),还有两个等效但稍少用的位运算方式:
立即学习“Java免费学习笔记(深入)”;
-
n & (−n) == n:利用补码特性,
−n是 n 的二进制取反加 1,它能提取最低位的 1;当 n 只有一个 1 时,该值等于 n 自身 - Integer.bitCount(n) == 1:统计二进制中 1 的个数,为 1 且 n > 0 即可判定
前两者是纯位运算,后者调用标准库,语义更直白但底层仍依赖位操作优化。
实际写法与注意事项
推荐写成简洁、安全的一行表达式:
public static boolean isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}- 括号不能省:
n & n - 1 == 0会先算n - 1 == 0(布尔值),再和 n 做 &,逻辑错误 - long 类型需写成
n > 0L && (n & (n - 1L)) == 0L,避免字面量默认为 int 导致溢出 - 该方法不适用于浮点数或大整数(BigInteger),需另作处理


















