正数的补码与原码一致,负数的补码与原码不同,Java中的<< / >>/>>>均是对补码操作(java中存储的也只是补码),如果补码是负数,需要再转换为原码才是真实的负数值。
1 << 带符号左移
正数、负数的符号位不变(无溢出时),右边补0。 左移位 = *2的n次方
比如: 对-3左移3位 -3<<3
<< / >> 都是要关照符号位的,所以
-3的补码11111111 11111111 11111111 11111101 左移3位后为
新的补码11111111 11111111 11111111 11101000 ,
(除符号位外,各位取反再加1)新的原码为:10000000 00000000 00000000 00100111,转为整数即-24
2 >> 带符号右移
正数、负数的符号位不变,左边补符号位,如果是正数则左边补0,如果是负数则左边补1。 正数:右移位 = /2的n次方 负数需要根据补码操作再还原。
比如: 对-3右移3位 -3>>3 ,
就是对-3的补码11111111 11111111 11111111 11111101右移3位,结果为:
1 111 1111111 11111111 11111111 11111,由于是负数,高位需要补1(正数高位补0),而
1 111 1111111 11111111 11111111 11111
的原码为10000000 00000000 00000000 00000001,结果为-1,所以-3>>3的结果整数值为-1
3 >>> 无符号右移
对-3进行无符号右移, -3>>>3,由于>>>是不顾符号的,高位全部补0
11111111 11111111 11111111 11111101 无符号右移3位为
000 11111111 11111111 11111111 11111
由于无符号右移之后为正数,正数的补码和原码是一致的,所以 -3>>>3的值即为
000 11111111 11111111 11111111 11111
的值,变成整数输出为:02^31+02^30+02^29+12^28+12^27+.....+12^1+1*2^0=536870911
4 无<<<运算符
代码
System.out.println("-----------");
System.out.println(-99 >> 2);//-25
System.out.println(-99 >>> 2);//1073741799
System.out.println(-99 << 2);//-396
System.out.println("-----------");
System.out.println(-3 >> 3);//
System.out.println(-3 >>> 3);//
System.out.println(-3 << 3);//
```
输出
-----------
-25
1073741799
-396
-----------
-1
536870911
-24