1. 位移操作符
1.1. 没有无符号左移
1.2. 无符号右移: >>>
1.3. 有符号左移: <<
1.4. 有符号右移: >>
2. 左移规则
2.1. 右边空出来的位用0填补。
2.2. 高位左移溢出则舍弃高位。
3. 右移规则
3.1. 左边空出的位用0或者1填补。正数用0填补, 负数用1填补。
3.2. 低位右移溢出则舍弃该位。
4. Java位移结果是整数。
5. 分析几个右移操作
5.1. 0的有符号右移1位操作
0的补码: 0000 0000 0000 0000 0000 0000 0000 0000
0右移1位, 高位用0填补: 0000 0000 0000 0000 0000 0000 0000 0000
结果是: 0
5.2. 0的无符号右移1位操作
0的补码: 0000 0000 0000 0000 0000 0000 0000 0000
0右移1位, 高位用0填补: 0000 0000 0000 0000 0000 0000 0000 0000
结果是: 0
5.3. 1的有符号右移1位操作
1的补码: 0000 0000 0000 0000 0000 0000 0000 0001
1右移1位, 高位用0填补: 0000 0000 0000 0000 0000 0000 0000 0000
结果是: 0
5.4. 1的无符号右移1位操作
1的补码: 0000 0000 0000 0000 0000 0000 0000 0001
1右移1位, 高位用0填补: 0000 0000 0000 0000 0000 0000 0000 0000
结果是: 0
5.5. 127的有符号右移1位操作
127的补码: 0000 0000 0000 0000 0000 0000 0111 1111
127右移1位,高位用0填补: 0000 0000 0000 0000 0000 0000 0011 1111
结果是: 63
5.6. 127的无符号右移1位操作
127的补码: 0000 0000 0000 0000 0000 0000 0111 1111
127右移1位,高位用0填补: 0000 0000 0000 0000 0000 0000 0011 1111
结果是: 63
5.7. char类型-1的有符号右移1位操作
-1的原码: 1000 0001
-1的反码: 1111 1110
-1的补码: 1111 1111
-1转换成整形,高位用1填补: 1111 1111 1111 1111 1111 1111 1111 1111
-1右移1位, 高位用1填补: 1111 1111 1111 1111 1111 1111 1111 1111
-1右移1位后的反码: 1111 1111 1111 1111 1111 1111 1111 1110
-1右移1位后的原码: 1000 0000 0000 0000 0000 0000 0000 0001
结果是: -1
5.8. char类型-1的无符号右移1位操作
-1的原码: 1000 0001
-1的反码: 1111 1110
-1的补码: 1111 1111
-1转换成整形,高位用1填补: 1111 1111 1111 1111 1111 1111 1111 1111
-1右移1位, 高位用0填补: 0111 1111 1111 1111 1111 1111 1111 1111
结果是: 2147483647
5.9. char类型-127的有符号右移1位操作
-127的原码: 1111 1111
-127的反码: 1000 0000
-127的补码: 1000 0001
-127转换成整形高位用1填: 1111 1111 1111 1111 1111 1111 1000 0001
-127右移1位, 高位用1填补: 1111 1111 1111 1111 1111 1111 1100 0000
-127右移1位的反码: 1111 1111 1111 1111 1111 1111 1011 1111
-127右移1位的原码: 1000 0000 0000 0000 0000 0000 0100 0000
结果是: 64
5.10. char类型-127的无符号右移1位操作
-127的原码: 1111 1111
-127的反码: 1000 0000
-127的补码: 1000 0001
-127转换成整形高位用1填: 1111 1111 1111 1111 1111 1111 1000 0001
-127右移1位, 高位用0填补: 0111 1111 1111 1111 1111 1111 1100 0000
结果是: 2147483584
5.11. char类型-128的有符号右移1位操作
-128的补码: 1000 0000
-128转换成整形高位用1填: 1111 1111 1111 1111 1111 1111 1000 0000
-128右移1位, 高位用1填补: 1111 1111 1111 1111 1111 1111 1100 0000
-128右移1位的反码: 1111 1111 1111 1111 1111 1111 1011 1111
-128右移1位的原码: 1000 0000 0000 0000 0000 0000 0100 0000
结果是: 64
5.12. char类型-128的无符号右移1位操作
-128的补码: 1000 0000
-128转换成整形高位用1填: 1111 1111 1111 1111 1111 1111 1000 0000
-128右移1位, 高位用0填补: 0111 1111 1111 1111 1111 1111 1100 0000
结果是: 2147483584
6. 分析几个左移例子
6.1. 2147483647左移1位
2147483647补码: 01111111 11111111 11111111 11111111
2147483647左移1位低位用0填补: 11111111 11111111 11111111 11111110
2147483647左移1位, 反码: 11111111 11111111 11111111 11111101
2147483647左移1位, 原码: 10000000 00000000 00000000 00000010
结果: -2
6.2. -2147483648左移1位
-2147483648补码: 10000000 00000000 00000000 00000000
-2147483648左移1位低位用0填补: 00000000 00000000 00000000 00000000
结果: 0
6.3. -2147483647左移1位
-2147483647原码: 11111111 11111111 11111111 11111111
-2147483647反码: 10000000 00000000 00000000 00000000
-2147483647补码: 10000000 00000000 00000000 00000001
-2147483647左移1位低位用0填补: 00000000 00000000 00000000 00000010
结果: 2
7. byte类型的所有值左移例子
// 位移的结果是整数
// 左移没有整数范围都是乘以2
public static void byteLeftShift() {
int count = 0;
for(byte i = Byte.MIN_VALUE; count < Math.abs(Byte.MIN_VALUE) + Byte.MAX_VALUE + 1; i++) {
count++;
System.out.println(i + " " + (i << 1));
}
}
8. byte类型的所有值右移例子
// 位移的结果是整数
// 正数的右移, 移动1位是除2, 移动2位是除4, ..., 这个规律是完全正确的
// 负数右移按除法操作不可靠
public static void byteRightShift() {
int count = 0;
for(byte i = Byte.MIN_VALUE; count < Math.abs(Byte.MIN_VALUE) + Byte.MAX_VALUE + 1; i++) {
count++;
System.out.println(i + " " + (i >> 1) + " " + (i >>> 1));
}
}