右移和左移的工作方式相同,这里是右移的工作原理;右移:右移运算符 >> 将值中的所有位向右移动指定的次数。它的一般形式:
value >> num
此处,num 指定将 value 中的值右移的位置数。也就是说,>> 将指定值中的所有位向右移动 num 指定的位数。以下代码片段将值 32 向右移动两个位置,从而将 a 设置为 8:
int a = 32;
a = a >> 2; // a now contains 8
当一个值具有“移出”的位时,这些位将丢失。例如,下一个代码片段将值 35 向右移动两个位置,这导致两个低位丢失,导致 a 再次被设置为 8。
int a = 35;
a = a >> 2; // a still contains 8
查看二进制中的相同操作可以更清楚地显示这是如何发生的:
00100011 35 >> 2
00001000 8
每次将一个值向右移动时,它都会将该值除以 2,并丢弃任何余数。您可以利用这一点进行高性能整数除以 2。当然,您必须确保没有将任何位移出右端。当您右移时,右移所暴露的最高(最左)位将用最高位的先前内容填充。这称为符号扩展,用于在您向右移动负数时保留负数的符号。例如,–8 >> 1
is –4
,在二进制中,是
11111000 –8 >>1
11111100 –4
有趣的是,如果将 –1 右移,结果始终保持为 –1,因为符号扩展不断在高位中引入更多的位。有时,当您将它们向右移动时,不希望对值进行符号扩展。例如,以下程序将字节值转换为其十六进制字符串表示形式。请注意,移位的值通过与 0x0f 进行与运算来屏蔽,以丢弃任何符号扩展位,以便该值可以用作十六进制字符数组的索引。
// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}
这是该程序的输出:
b = 0xf1