Java中的左移、右移、无符号右移

首先明确一点,移位操作的对象是「补码」

关于原码和补码

右移

又称带符号右移,>>

  • 正数补码符号位为 0\text 0 。右移后会在最高位补 0\text 0
  • 负数补码符号位是 1\text 1 。右移后会在最高位补 1\text 1

无符号右移

无符号右移,>>>

无论是正数还是负数,右移后在最高位一律补 0\text 0

例子1:

int x = Integer.MIN_VALUE

x=x=-231=2^{31}=-21474836482147483648

执行运算 x >> 1x >>> 1

image-20220722220412573

例子2:

x=2x = -2 计算 x>>1x>>1 ,计算结果应当是 -1

计算机的计算过程

1
2
3
4
5
6
7
8
9
10
-2的原码
0b1000 0000 0000 0000 0000 0000 0000 0010
-2的补码
0b1111 1111 1111 1111 1111 1111 1111 1110
右移1位,最高位补1
0b1111 1111 1111 1111 1111 1111 1111 1111
现在求原码
0b1000 0000 0000 0000 0000 0000 0000 0000 // 除符号位,按位取反
0b1000 0000 0000 0000 0000 0000 0000 0001 // 加1
即为-1

左移

左移,<<

左移,低位补 0\text 0

注意左移可能会出现"越界"

举例说明:

int x = Integer.MAX_VALUE

x=231x=2^{31}-1=21474836471=2147483647

执行运算 x << 1,结果是 -2\textit-2

image-20220722220446617