提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、位运算有哪些?
左移运算 <<
右移运算 >>
无符号右移 >>>
二、被移动的是什么东西?
补码!
三、运算示例
1. 左移 <<
规则:
高位丢弃,低位补0
- 示例一
public class NumberMoveBit{
public static void main(String[] args){
int a = Integer.MAX_VALUE; // 2147483647
a = a << 1;
System.out.println(a);
System.out.println(Integer.toBinaryString(a)); // 输出的是保存的’补码‘
}
}
输出结果:
-2
11111111111111111111111111111110
分析:
a的原码 0111 1111 1111 1111 1111 1111 1111 1111
a的反码 0111 1111 1111 1111 1111 1111 1111 1111 // 正数不变
a的补码 0111 1111 1111 1111 1111 1111 1111 1111 // 正数不变
左移1位 1111 1111 1111 1111 1111 1111 1111 1110 // 还是’补码‘,最高位符号位也参与移位,代表负数
转换为反码 1111 1111 1111 1111 1111 1111 1111 1101 // (负数)反码 = 补码 - 1
转换为原码 1000 0000 0000 0000 0000 0000 0000 0010 // -2
- 示例二
public class NumberMoveBit{
public static void main(String[] args){
int a = Integer.MIN_VALUE + 1; // -2147483647
a = a << 1;
System.out.println(a);
System.out.println(Integer.toBinaryString(a)); // 输出的是保存的’补码‘
}
}
输出结果:
2
10 (i.e. 0000 0000 0000 0000 0000 0000 0000 0010)
分析:
a的原码 1111 1111 1111 1111 1111 1111 1111 1111
a的反码 1000 0000 0000 0000 0000 0000 0000 0000 // 符号位不变,数值位取反
a的补码 1000 0000 0000 0000 0000 0000 0000 0001 // 反码 + 1
左移1位 0000 0000 0000 0000 0000 0000 0000 0010 // 还是’补码‘,最高位符号位也参与移位,
转换为反码 0000 0000 0000 0000 0000 0000 0000 0010 // (正数)反码 = 补码
转换为原码 0000 0000 0000 0000 0000 0000 0000 0010 // 2 (正数)源码 = 反码
2. 右移 >>
规则:
最高位符号位为0时,高位空缺补0
最高位符号位为1时,高位空缺补1
- 示例一
public class NumberMoveBit{
public static void main(String[] args){
int a = 16
a = a >> 1;
System.out.println(a);
System.out.println(Integer.toBinaryString(a)); // 输出的是保存的’补码‘
}
}
输出结果:
8
1000 (i.e. 0000 0000 0000 0000 0000 0000 0000 1000)
分析:
a的原码 0000 0000 0000 0000 0000 0000 0001 0000 // 16
a的反码 0000 0000 0000 0000 0000 0000 0001 0000 // 正数不变
a的补码 0000 0000 0000 0000 0000 0000 0001 0000 // 正数不变
右移1位 0000 0000 0000 0000 0000 0000 0000 1000 // 还是’补码‘;最高位符号位也参与移位,由于原本最高位为0,所以高位空缺补0
转换为反码 0000 0000 0000 0000 0000 0000 0000 1000 // (负数)反码 = 补码 - 1
转换为原码 0000 0000 0000 0000 0000 0000 0000 1000 // 8
- 示例二
public class NumberMoveBit{
public static void main(String[] args){
int a = -16
a = a >> 1;
System.out.println(a);
System.out.println(Integer.toBinaryString(a)); // 输出的是保存的’补码‘
}
}
输出结果:
-8
11111111111111111111111111111000
分析:
a的原码 1000 0000 0000 0000 0000 0000 0001 0000 // -16
a的反码 1111 1111 1111 1111 1111 1111 1110 1111 // 符号位不变,数值位取反
a的补码 1111 1111 1111 1111 1111 1111 1111 0000 // 反码 + 1
右移1位 1111 1111 1111 1111 1111 1111 1111 1000 // 还是’补码‘;最高位符号位也参与移位,由于原本最高位为1,所以高位空缺补1
转换为反码 1111 1111 1111 1111 1111 1111 1111 0111 // (负数)反码 = 补码 - 1
转换为原码 1000 0000 0000 0000 0000 0000 0000 1000 // -8
3. 无符号右移 >>>
规则:
无论最高位符号位为0还是1,高位空缺都补0
- 示例一
public class NumberMoveBit{
public static void main(String[] args){
int a = -16
a = a >>> 1;
System.out.println(a);
System.out.println(Integer.toBinaryString(a)); // 输出的是保存的’补码‘
}
}
输出结果:
2147483640
1111111111111111111111111111000 (i.e. 0111 1111 1111 1111 1111 1111 1111 1000)
分析:
a的原码 1000 0000 0000 0000 0000 0000 0001 0000 // -16
a的反码 1111 1111 1111 1111 1111 1111 1110 1111 // 符号位不变,数值位取反
a的补码 1111 1111 1111 1111 1111 1111 1111 0000 // 反码 + 1
右移1位 0111 1111 1111 1111 1111 1111 1111 1000 // 还是’补码‘;最高位符号位也参与移位,高位空缺直接补0
转换为反码 0111 1111 1111 1111 1111 1111 1111 1000 // 正数不变
转换为原码 0111 1111 1111 1111 1111 1111 1111 1000 // 2147483640