理解无符号右移

时间:2015-03-08 07:31:55

标签: java

JLS 15.19描述了>>>运营商的公式。

  

n>>>的值s是n右移位s位   零扩展,其中:

     

如果n为正,则结果与n>>的结果相同。第

     

如果n为负数且左侧操作数的类型为int,则   结果等于表达式(n>> s)+(2<< s)的结果。

     

如果n为负且左侧操作数的类型为long,则   结果等于表达式(n>&gt; s)+(2L <&lt; ~s)的结果。

为什么n >>> s = (n >> s) + (2 << ~s)~s = 31 - s int~s = 63 - s的长度为何?

2 个答案:

答案 0 :(得分:2)

如果n为负,则表示符号位已设置。

>>> s表示将s位置向右移动,将零引入空出的位置。

>> s表示将s位置向右移动,将符号位的副本引入空出的位置。

E.g。

10111110000011111000001111100000 >>> 3 == 00010111110000011111000001111100

10111110000011111000001111100000 >>  3 == 11110111110000011111000001111100

显然,如果n不是否定的,则n >> sn >>> s是相同的。如果n为否定,则差异将包含左侧的s个,后跟全部为零。

换句话说:

(n >>> s) + X == n >> s        (*)

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

由于32 - s中有X个零,X中最右边的一个出现在1 << (32 - s)中的一个位置,等于{{ 1}},与2 << (31 - s)相同(因为2 << ~s和移位金额为~s == -1 - s s的模32工作。

现在将int添加到2 << ~s时会发生什么?你得零!让我们在X的案例中证明这一点。请注意,随身携带从左侧消失。

s == 7

遵循 11111110000000000000000000000000 + 00000010000000000000000000000000 ________________________________ 00000000000000000000000000000000 。因此,-X == 2 << ~s-X的两边添加(*)

n >>> s == (n >> s) + (2 << ~s)

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

答案 1 :(得分:2)

如果你不熟悉他所假设的基础知识,这里有一些额外的背景可以帮助你理解pbabcdefp的答案:

要理解按位运算符,您必须将数字视为二进制数字的字符串,例如。 20 = 00010100-4 = 11111100(为了清晰起见而不必编写如此多的数字,我将把所有二进制数写为byte s; int s是相同的但是四倍的时间)。如果您不熟悉二进制和二进制操作,you can read more here。注意第一个数字是如何特殊的:它使得数字为负数,就好像它有一个可能最负数的位值(记住基本数学,数/数百位?),所以Byte.MIN_VALUE = -128 = 1000000和设置任何其他位为1总是增加数字。要轻松读取11110011等负数,请知道-1 = 11111111,然后将0读取为正数为1,那么该数字与-1的距离为-1。所以11110011 = -1 - 00001100 = -1 - 12 = -13

同时理解~s是按位NOT:它取所有数字并翻转它们,这实际上相当于~s = -1 - s。例如~5 (00000101)-6 (11111010)。观察我建议的读取负二进制数的方法只是一个技巧,能够读取数字的按位NOT而不是数字本身,这对于接近零的负数更容易,因为这些数字较少01 s。