我知道>>之间的区别和>>>。但是我没有得到我预期的输出。
例如
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 ?
感谢。
答案 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只需对整数值的二进制补码表示进行符号扩展,以填充更宽的格式。