在计算机中,整数总是以二进制的形式表示。例如,int类型的整数7使用4字节表示的二进制如下:

00000000 0000000 0000000 00000111

可以对整数进行移位运算。对整数7左移1位将得到整数14,左移两位将得到整数28

int n = 7;       // 00000000 00000000 00000000 00000111 = 7
int a = n << 1;  // 00000000 00000000 00000000 00001110 = 14
int b = n << 2;  // 00000000 00000000 00000000 00011100 = 28
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912

左移29位时,由于最高位变成1,因此结果变成了负数。

类似的,对整数28进行右移,结果如下:

int n = 7;       // 00000000 00000000 00000000 00000111 = 7
int a = n >> 1;  // 00000000 00000000 00000000 00000011 = 3
int b = n >> 2;  // 00000000 00000000 00000000 00000001 = 1
int c = n >> 3;  // 00000000 00000000 00000000 00000000 = 0

如果对一个负数进行右移,最高位的1不动,结果仍然是一个负数:

int n = -536870912;
int a = n >> 1;  // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2;  // 11111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1

还有一种无符号的右移运算,使用>>>,它的特点是不管符号位,右移后高位总是补0,因此,对一个负数进行>>>右移,它会变成正数,原因是最高位的1变成了0

int n = -536870912;
int a = n >>> 1;  // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2;  // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1

byteshort类型进行移位时,会首先转换为int再进行位移。

仔细观察可发现,左移实际上就是不断地×2,右移实际上就是不断地÷2。