Java中的按位右移运算符

MSh*_*MSh 4 java bit-manipulation bitwise-operators

在Java中,-4 >> 2给出-1但-5 >> 2给出-2.谁能解释为什么?这是一个示例代码:

byte r=-5;
r>>=2;
System.out.println(r);
Run Code Online (Sandbox Code Playgroud)

同样在这种情况下>>和>>>运算符给出相同的答案.任何人都可以解释一下吗?

rge*_*man 6

你可以看看这些位.使用二进制补码表示法,为-4-5简洁的位数仅显示最后8位:

-4: 1111 1100      
-5: 1111 1011
Run Code Online (Sandbox Code Playgroud)

位移到右侧2位,带符号扩展:

-4 >> 2: 1111 1111 (-1)
-5 >> 2: 1111 1110 (-2)
Run Code Online (Sandbox Code Playgroud)

通常,您认为>>>不使用符号扩展,这是正确的,但在这种情况下:

r >>>= 2;
Run Code Online (Sandbox Code Playgroud)

... 使用二进制数字提升将值r提升int为位移操作,但复合赋值运算符将返回的值转换回byte,并且移入的零"消失".

byte r = -5;     // 1111 1100
r >>>= -2;       // promoted to int:   11111111 11111111 11111111 11111010
                 // bit shift:         00111111 11111111 11111111 11111110
                 // cast back to byte: 11111110 (-2)
Run Code Online (Sandbox Code Playgroud)

JLS,第15.26.2,谈论了复合赋值运算符完成铸造操作:

形式E1 op = E2的复合赋值表达式等效于E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1仅被评估一次.

也就是说,在这种情况下,位移的结果被转换回来byte.

当值为ris 时,会发生相同的强制转换操作-4.

请注意,如果未完成赋值部分,则您将看不到相同的答案,因为它不会将结果强制转换为byte:

System.out.println(r >>> 2);
Run Code Online (Sandbox Code Playgroud)

然后你会看到:

1073741822
Run Code Online (Sandbox Code Playgroud)