JLS 15.19 描述了 >>> 运算符的公式。



为什么 n >>> s = (n >> s) + (2 << ~s) ,其中 ~s = 31 - sint~s = 63 - s 很长?

最佳答案

如果 n 为负,则表示设置了符号位。
>>> s 意味着将 s 位置向右移动,将零引入空位。
>> s 意味着将 s 位置向右移动,将符号位的副本引入空出的插槽中。

例如。

10111110000011111000001111100000 >>> 3 == 00010111110000011111000001111100

10111110000011111000001111100000 >>  3 == 11110111110000011111000001111100

显然如果 n 不是负数,那么 n >> sn >>> s 是一样的。如果 n 为负,则差异将由左侧的 s 1 和全零组成。

换句话说:
(n >>> s) + X == n >> s        (*)

其中 Xs 后跟 32 - s 零组成。

因为 32 - s 中存在 X 0,所以 X 中最右边的 1 出现在 1 << (32 - s) 中 1 的位置,等于 2 << (31 - s) ,与 2 << ~s 相同(因为 ~s == -1 - s 和 shift 量对 int 进行模32) .

现在将 2 << ~s 添加到 X 会发生什么?你得到零!让我们在 s == 7 案例中演示这一点。请注意,进位从左侧消失了。
  11111110000000000000000000000000
+ 00000010000000000000000000000000
  ________________________________
  00000000000000000000000000000000

它遵循 -X == 2 << ~s 。因此将 -X 添加到 (*) 的两边我们得到
n >>> s == (n >> s) + (2 << ~s)

对于 long ,它完全相同,只是移位量以 64 为模完成,因为 long 有 64 位。

关于java - 理解无符号右移,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28924151/

10-11 03:44