Java中的>>和>>>运算符有什么区别?

17

我没有我的Java参考书,用Google很难找到答案。

在Java中,“>>”和“>>>”运算符之间有什么区别?

int value = 0x0100;

int result = (value >> 8);
System.out.println("(value >> 8) = " + result);  // Prints: "(value >> 8) = 1"

result = (value >>> 8);
System.out.println("(value >>> 8) = " + result); // Prints: "(value >>> 8) = 1"

1
可能的重复问题:>>>和>>之间的区别>>>和>>运算符之间的区别 - Oriol
9个回答

23

带符号整数使用高位比特来表示符号。

>> 保留符号,而 >>> 不保留符号。这就是为什么 >> 被称为 算术移位,而 >>>逻辑移位 的原因。

这样,您可以做到(假设是32位整数):

  • -10 >> 1 得到 -5 (0xFFFFFFF6 >> 1 得到 0xFFFFFFFB - 注意高位比特保持不变。)
  • -10 >>> 1 得到 2147483643 (0xFFFFFFF6 >>> 1 得到 0x7FFFFFFB - 注意所有比特都被移动了,所以最高位现在是零。根据二进制补码算法,数字不再是负数。)

对于正整数,>>>>> 行为相同,因为最高位已经是零。

这也解释了为什么没有需要一个 <<< 运算符。由于通过将比特向左移动将破坏符号,它将映射到没有合理算术操作的值。


@BillK 虽然答案不错,但你有没有注意到当你要发表评论时,SO会要求你不要写类似于 +1 或者 谢谢 的内容呢? - dryairship
@PriydarshiSingh 我通常不这样做,但我认为指出这个答案应该在被接受的答案之上投票是有用的(似乎起作用了)。如果我只说“最有用的答案”会更好吗?此外,您是否绝对确定该指南存在于'09年? - Bill K

19

>>>逻辑右移>>算术右移

  • 0xDEADBEEF >>> 80x00DEADBE (逻辑右移, 您想要的那个)
  • 0xDEADBEEF >> 80xFFDEADBE (算术右移)

9

来自Java笔记:位运算符

n >> p (右移) 将n的位向右移动p个位置。如果n是2进制补码表示的有符号数,则符号位会移到高位。

例子: 5 >> 2 = 1

n >>> p (无符号右移) 将n的位向右移动p个位置。高位补0。

例子: -4 >>> 28 = 15


7

对于正数,没有区别。负数(二进制补码)在 >>> 时将填充零,在 >> 时将填充一。

1010 0110 >>>2 = 0010 1001

1010 0110 >> 2 = 1110 1001


5

正确答案已经发布多次,但并非来自权威来源。

这段内容来自 JLS§15.19 移位运算符

“移位运算符”包括左移位<<、有符号右移位>>和无符号右移位>>>;它们在语法上是左关联的(从左到右分组)。移位运算符的左操作数是要移位的值,右操作数指定移位距离。 ... n>>s的值是n向右移动s个比特位,带符号扩展。结果值为⌊n/2^s⌋。对于非负的n值,这相当于整数除法的截断,由整数除法运算符/计算,除以2的s次幂。 n>>>s的值是n向右移动s个比特位,零扩展。如果n是正数,则结果与n>>s的结果相同;如果n是负数,则结果等于表达式(n>>s)+(2<<~s)的结果,如果左操作数的类型是int,则结果等于表达式(n>>s)+(2L<<~s)的结果。添加的术语(2<<~s)(2L<<~s)取消了传播的符号位。(请注意,由于移位运算符的右操作数的隐式掩码,当移位int值时,~s作为移位距离等同于31-s,当移位long值时,~s等同于63-s。)

1
非常感谢您的回复。它解答了我另一个问题:在只有逻辑移位的CPU上如何有效地执行算术移位。“(n>>s)+(2<<~s)”似乎是一个不错的答案 :-) - Mecki

2

>> 是一种算术移位,它在任何“空位”中保留符号位。而另一种是逻辑移位,它用零来填充空位。


1

算术右移 >> 对于有符号整数而言是除以二,而逻辑右移 >>> 对于无符号数字而言是除以二(如果你将有符号 Java int 的位模式解释为无符号整数)。


0

一些信息

>> 运算符保留最左边的位。最左边的位填充了先前的内容。这与符号扩展有关。在这种情况下,左侧有一个 1 并且被保留。如果您不想保留左侧的 1,请使用 >>> 运算符,它将 0 移入最左侧的位。


0

这与有符号数学有关。 >>> 用零填充高位比特,>> 保留符号位并将其拉入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接