位运算判断2的N次幂

思考

如何判断一个数是不是2的N次幂?
难道要一直除下去?一直乘过去?还是打表?
我们就不能简单一些处理这个问题吗?
那就有了这篇博客的内容——位运算判断一个数是不是2的N次幂……

核心算法

其实就是:(num & num-1) == 0

&表示按位取且,运算规律是(在二进制的情况下):

  • 1 & 1 = 1
  • 1 & 0 = 0
  • 0 & 1 = 0
  • 0 & 0 = 0

Java编程实现

private static boolean isPowOfTwo(int num) {
    return (num & num-1) == 0;
}

算法正确性

我们把一个十进制的数当成二进制来看。

Q:2的N次幂的二进制有什么特点?

先枚举一些例子:
1 → 00000001
2 → 00000010
4 → 00000100
8 → 00001000
……

A:二进制表示的情况下只有一位(非最高位)是1

我们不加以形式化地证明一下:

假设不是2的N次幂,这个数起码就要比2大(我们只考虑正整数),至少也是00000011(8位二进制表示),那么非0的就不止1个,至少2位非0。
那么对于num-1,一定不会去到最高位非0位去“借位”,所以最高非0位一定不変,还是1。
既然我们按位取且,所以num & num-1(注意位运算的优先级弱于加减,可以这么写而不加括号)至少会在num原先的最高非0位保持1,(因为1&1=1),这样的结果就不可能是0(因为0是00000000)。

所以我们就能发现,只有在num是2n(0≤n, n∈N+)的情况下,(num & num-1) == 0为真。

完整代码

import java.util.Scanner;

public class JudgePowOfTwo {

    private static boolean isPowOfTwo(int num) {
        return (num & num-1) == 0;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        scanner.close();
        System.out.println(isPowOfTwo(num));
    }
    
}
发布了481 篇原创文章 · 获赞 974 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_43896318/article/details/104251718
今日推荐