我正尝试向右移位,以便将某些位与字节隔离,因此我希望进行无符号移位,据我的理解,“新”位应为零。但是,我发现在测试中>>>与>>没有什么区别。 -128 >> 4 = -8如预期,但-128 >>> 4应该为8,但我仍然为-8。
byte data = (byte)-128;
System.out.println((byte)(data >>> 4));
System.out.println((byte)(data >> 4));
感谢您的帮助。
答案 0 :(得分:7)
无符号右移运算符确实在此代码中执行无符号右移;由于从byte
到int
的隐式转换,它只是被隐藏了。说Java语言规范(§15.19):
运算符
<<
(左移),>>
(有符号右移)和>>>
(无符号右移)称为移位运算符。移位运算符的左操作数是要移位的值;右侧操作数指定移位距离。 [...]对每个操作数分别执行一元数值提升(第5.6.1节)。
一元数字促销表示(§5.6.1):
[...]如果操作数是编译时类型
byte
,short
或char
,则将其提升为int
类型的值不断扩大的原始转换(第5.1.2节)。
因此,您的代码的评估如下:
byte
的左操作数的-128
值>>>
被提升为int
的值-128
,即0b11111111111111111111111110000000
二进制。int
值进行无符号右移,结果为268435448
,二进制形式为0b00001111111111111111111111111000
。请注意,最左边的四个位为零,就像您从无符号右移中所期望的那样。(byte)
,得到结果-8
。使用REPL:
> byte b = -128;
> int shifted = b >>> 4;
> shifted
268435448
> (byte) shifted
-8
对于所需的行为,可以使用& 0xFF
进行从byte
到int
的“无符号”转换:
> ((b & 0xFF) >>> 4)
8
答案 1 :(得分:1)
有符号的右移运算符'>>'使用符号位填充尾随位置,而无符号的右移运算符'>>'不使用符号位填充尾随位置。它总是以0s填充尾随位置