目录
需要了解的几个点
移位的过程
示例
特殊情况
前置知识点
首先需要明确的几个点
java
中数字是以二进制补码的形式进行存储和计算的java
中的左移不区分有符号和无符号,而左移需要区分byte、short
两种类型的移位运算会转换成int
类型的移位运算
移位的过程
如流程图所示,转换过程为:
- 先将数字转换为它的二进制补码形式
- 对于左移,将所有比特位全部移动,右边空位补
0
- 对于无符号右移,将所有比特位全部右移,左边空位补
0
- 正数的有符号右移和无符号右移相同
- 负数的有符号位移需要符号位保持不动,其他位右移,空位补
1
- 移位之后,按照补码求原码的方式,求出移位后数的值
示例
用-4和4来作为一个移位的示例
二进制补码 | >>1 | >>>1 | <<1 | |
---|---|---|---|---|
4 | 00000000 00000000 00000000 00000100 | 00000000 00000000 00000000 00000010 | 00000000 00000000 00000000 00000010 | 00000000 00000000 00000000 00001000 |
-4 | 11111111 11111111 11111111 11111100 | 11111111 11111111 11111111 11111110 | 01111111 11111111 11111111 11111110 | 11111111 11111111 11111111 11111000 |
对于4
来说,由于它是正数,它的补码、原码相同,可以很明显的看出:
4 >>1 = 2;
4 >>>1 = 2;
4 <<1 = 8;
对于-4
来说,由于它是负数,所以原码和补码不相同,需要对移位后的补码求原码:
-4不移位 | -4>>1 | -4>>>1 | -4<<1 | |
---|---|---|---|---|
补码 | 11111111 11111111 11111111 11111100 | 11111111 11111111 11111111 11111110 | 01111111 11111111 11111111 11111110 | 11111111 11111111 11111111 11111000 |
原码 | 10000000 00000000 00000000 00000100 | 10000000 00000000 00000000 00000010 | 01111111 11111111 11111111 11111110 | 10000000 00000000 00000000 00001000 |
十进制数 | -4 | -2 | 2,147,483,646 | -8 |
特殊情况
先看下面的例子
@Test
public void test(){
int a=1073741824;
int b= a<<1;
System.out.println("a="+Integer.toBinaryString(a));
System.out.println("b="+Integer.toBinaryString(b));
System.out.println("a="+a);
System.out.println("b="+b);
}
这个例子的输出为如下
a=1000000000000000000000000000000
b=10000000000000000000000000000000
a=1073741824
b=-2147483648
从上面可以看出,将a
左移1位后得到b
,对于b
的二进制补码,它没有对应的原码,实际上,b
也是int类型
的最小值,这个问题也同样出现在其他类型上。这个问题可以参考下面的文章:byte类型为什么是-128~127
前置知识点
什么是原码、补码、以及反码
** 这篇文章对于源码、补码、反码,这篇文章讲的很详细 **
** 原码 **:用最高位表示符号位,1
表示负号,0
表示正号。其他位存放该数的二进制的绝对值。
** 反码 **:正数的反码还是它本身,负数的反码是除符号位(即最高位)的其他位取反
** 补码 **: 正数的补码等于它的原码,负数的补码等于它的反码加一
原码 | 反码 | 补码 | |
---|---|---|---|
0 | 00000000 | 00000000 | 00000000 |
+1 | 00000001 | 00000001 | 00000001 |
+2 | 00000010 | 00000010 | 00000010 |
-1 | 10000001 | 11111110 | 11111111 |
-2 | 10000010 | 11111101 | 11111110 |
如何由补码求原码
- 正数的补码和原码相同
- 负数的原码等于其补码符号位不变,其余各位取反后加1