Java>>>运营商给出这个输出?这是真的吗?

时间:2017-08-29 16:45:08

标签: java

我知道>>之间的区别和>>>。但是我没有得到我预期的输出。

例如

byte foo;

// this part printing -61 so no problem with this part
foo = -121; // -121 = 10000111
// foo >> 1 = 11000011 = -61
System.out.println( (byte) (foo >> 1) );  


foo = -121; // -121 = 10000111
// foo >>> 1 = 01000011 = 67
System.out.println( (byte) (foo >>> 1) );
// problem: why is this part printing -61 instead of 67 ?

感谢。

2 个答案:

答案 0 :(得分:7)

>>>int值进行操作,因此它首先将其参数扩展为int。所以它被符号扩展到

 11111111111111111111111110000111

哪个逻辑右转移到

 01111111111111111111111111000011

当你将最后8位作为转换为byte时,给出

 11000011

是-61。

如果您在轮班之前不想要隐式符号扩展,那么您必须写

(byte) ((foo & 0xFF) >>> 1)

答案 1 :(得分:1)

此外还有一些背景信息Louis Wasserman's excellent answer

这在jls-15.19 Shift Operators中指定:

  

对每个操作数分别执行一元数字提升(第5.6.1节)。 (不对操作数执行二进制数字提升(第5.6.2节)。)

jls-5.6.1 Unary Numeric Promotion

  
      
  • 如果操作数是编译时类型Byte,Short,Character或Integer,则进行拆箱转换(第5.1.8节)。然后通过扩展原语转换(第5.1.2节)或标识转换(第5.1.1节)将结果提升为int类型的值。

  •   
  • 否则,如果操作数是编译时类型为Long,Float或Double,则进行拆箱转换(第5.1.8节)。

  •   
  • 否则,如果操作数是编译时类型byte,short或char,则通过扩展原语转换(第5.1.2节)将其提升为int类型的值。

  •   
  • 否则,一元数字操作数保持不变,不会被转换。

  •   

(强调我的)

5.1.2. Widening Primitive Conversion

  

将有符号整数值的扩展转换为整数类型T只需对整数值的二进制补码表示进行符号扩展,以填充更宽的格式。