JLS 15.19 描述了 >>>
运算符的公式。
为什么 n >>> s = (n >> s) + (2 << ~s)
,其中 ~s = 31 - s
为 int
和 ~s = 63 - s
很长?
最佳答案
如果 n
为负,则表示设置了符号位。>>> s
意味着将 s
位置向右移动,将零引入空位。>> s
意味着将 s
位置向右移动,将符号位的副本引入空出的插槽中。
例如。
10111110000011111000001111100000 >>> 3 == 00010111110000011111000001111100
10111110000011111000001111100000 >> 3 == 11110111110000011111000001111100
显然如果
n
不是负数,那么 n >> s
和 n >>> s
是一样的。如果 n
为负,则差异将由左侧的 s
1 和全零组成。换句话说:
(n >>> s) + X == n >> s (*)
其中
X
由 s
后跟 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/