原码、反码和补码复习
对于一个数,计算机需要保存的是它的二进制形式。但是对于有符号数,又应该怎样处理呢?原码、反码、补码就是机器存储一个有符号数的具体编码方式。
原码
原码就是符号位加上数值的绝对值,即用第一位表示符号,其余位表示值。比如:如果是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;
}
}