概念
右移运算符是将一个二进制数按指定移动的位数向右移动。
移动过程中,正数最高位补0,负数最高位补1,无符号数最高位补0。
补码
在计算机系统中,数值一律用补码来表示和存储,其中最高位表示符号位,1表示负数,0表示正数。
- 正数的补码是原码自身。
- 负数补码是通过原码计算得到,计算过程为:符号位不变,其余位按照原码取反加1
补码计算示例
以计算十进制-100的补码为例,计算过程为:
-100的原码:10000000 00000000 00000000 01100100
符号位保持不变,取反:11111111 11111111 11111111 10011011
加1后,-100补码为:11111111 11111111 11111111 10011100
右移运算
下面右移都是以整数为例,不考虑小数情况。
正数右移
正数右移高位需补0,以100右移4位为例:
操作 | 二进制 | 对应十进制 |
---|---|---|
补码 | 00000000 00000000 00000000 01100100 | 100 |
右移4位 | 00000000 00000000 00000000 00000110 | 6 |
源码 | 00000000 00000000 00000000 00000110 | 6 |
最后可得: 100 >> 4 = 6
正数的右移相当于除法,右移几位就除以2的几次方,如100>>4 等效 100/2^4
负数右移
负数右移高位需补1,以-100右移4位为例:
操作 | 二进制 | 对应十进制 |
---|---|---|
原码 | 10000000 00000000 00000000 01100100 | -100 |
转换为补码 | 11111111 11111111 11111111 10011100 | -100 |
右移4位,高位补1 | 11111111 11111111 11111111 11111001 | |
保留符号位,按位取反 | 10000000 00000000 00000000 00000110 | |
加1后转为源码 | 10000000 00000000 00000000 00000111 | -7 |
最后可得: -100 >> 4 = -7
负数的右移不等于除法,即负数右移不能按除以2的n次方计算(n表示移动位数)。
无符号右移
无符号右移和正数右移相同,都是高位补0,以-100右移4位为例:
操作 | 二进制 | 对应十进制 |
---|---|---|
原码 | 10000000 00000000 00000000 01100100 | -100 |
转换为补码 | 11111111 11111111 11111111 10011100 | -100 |
右移4位,高位补0 | 00001111 11111111 11111111 11111001 | |
转为原码 | 00001111 11111111 11111111 11111001 | 268435449 |
最后可得: -100 >>> 4 = 268435449
右移28位后,最高位为0表示正数,所以原码即为补码本身。
“>>>”是Java里的无符号右移操作符。
总结
正数的右移,负数的无符号右移,就是相应的补码移位所得,在高位补0即可。
负数的右移,就是补码高位补1,然后按位取反加1即可。