LeetCode #231 2的幂

317 阅读3分钟

原码、反码和补码复习

对于一个数,计算机需要保存的是它的二进制形式。但是对于有符号数,又应该怎样处理呢?原码、反码、补码就是机器存储一个有符号数的具体编码方式。

原码

原码就是符号位加上数值的绝对值,即用第一位表示符号,其余位表示值。比如:如果是8位二进制的正1和负1:

[+1] = [0000 0001]原 [-1] = [1000 0001]原

反码

反码的表示方法是:

  • 正数的反码是其本身;
  • 负数的反码是在其原码的基础上,符号位不变,其余各个位取反

[+1] = [0000 0001]原 = [0000 0001]反 [-1] = [1000 0001]原 = [1111 1110]反

补码

补码的表示方法是:

  • 正数的补码就是其本身;
  • 负数的补码是在其原码的基础上,符号位不变,其余各位取反,再+1。(也就是反码加1)

可以看得出来,不论那种编码形式,正数都是不变的;反码和补码主要用来处理负数。在计算机系统中,一般统一用补码来表示有符号数。 使用补码的好处是:

  • 解决了0的符号问题以及0的两个编码问题;
  • 可以将符号位和数值域统一处理,加法和减法也可以统一处理
  • 补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路;

位运算符

位运算就是直接对整数在内存中的二进制位进行操作。相比于普通的整数算术运算,位运算是底层运算,效率更高,代码也更加简洁。 Java中支持的位运算有:

  • &:按位与 如果相对应位都是1,则结果为1,否则为0
  • |:按位或 如果相对应位都是 0,则结果为 0,否则为 1
  • ~:按位非 按位取反运算符翻转操作数的每一位,即0变成1,1变成0
  • ^:按位异或 如果相对应位值相同,则结果为0,否则为1
  • <<:左位移运算符 左操作数按位左移右操作数指定的位数
  • >>:右位移运算符 左操作数按位右移右操作数指定的位数
  • >>>:无符号右移运算符 左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充

题目

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。 如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/po… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例

在这里插入图片描述

代码

package com.vleus.algorithm.bit_operator;

/**
 * @author vleus
 * @date 2021年08月02日 23:04
 */
public class PowerOfTwo {

    //方法一:连续除以2判断余数
    public boolean isPowerOfTwo(int n) {

        if (n <= 0) {
            return false;
        }

        //不停地除以2,直到结果为奇数
        while (n % 2 == 0) {
            n = n / 2;
        }

        //如果最终n变成了1,就是2的整次幂
        return n==1;
    }

    //方法二:位运算:与自身-1做位与,二进制的数与其-1的数字按位与肯定是0
    public boolean isPowerOfTow2(int n) {

        if (n <= 0) {
            return false;
        }

        return (n & n - 1) == 0;
    }

    //方法三:位运算:与自身-1做位与,二进制的数与其-1的数字按位与肯定是0
    public boolean isPowerOfTow3(int n) {

        if (n <= 0) {
            return false;
        }

        return (n & -n) == n;
    }

}