我想进行位右移操作,以便从一个字节中隔离出特定的位,因此我希望进行无符号移位,根据我的理解,“新”位应该是零。然而,我发现在我的测试中,“>>>”与“>>”没有任何区别。-128 >> 4 = -8,这是预期的结果,但是-128 >>> 4应该是8,但我仍然得到-8。
byte data = (byte)-128;
System.out.println((byte)(data >>> 4));
System.out.println((byte)(data >> 4));
感谢您的帮助。
我想进行位右移操作,以便从一个字节中隔离出特定的位,因此我希望进行无符号移位,根据我的理解,“新”位应该是零。然而,我发现在我的测试中,“>>>”与“>>”没有任何区别。-128 >> 4 = -8,这是预期的结果,但是-128 >>> 4应该是8,但我仍然得到-8。
byte data = (byte)-128;
System.out.println((byte)(data >>> 4));
System.out.println((byte)(data >> 4));
byte
到int
的隐式转换而被隐藏了。Java语言规范(§15.19)如此解释:操作符<<
(左移)、>>
(带符号右移)和>>>
(无符号右移)称为移位运算符。移位运算符的左操作数是要移位的值;右操作数指定了移位距离。[...]每个操作数都分别执行一元数值推广(§5.6.1)。
一元数值提升意味着(§5.6.1):
引用块:[...]如果操作数的编译时类型是byte
、short
或char
,则通过扩展原始转换(§5.1.2)将其提升为int
类型的值。
-128
是>>>
的左操作数,它是一个byte
值。根据规定,在执行移位操作之前将其提升为int
类型,并变成 -128
,在二进制中是0b11111111111111111111111110000000
。int
值进行无符号右移操作,结果为268435448
,在二进制中为0b00001111111111111111111111111000
。请注意,最左边的四位为零,这是您从无符号右移期望的结果。(byte)
类型,得到结果为-8
。> byte b = -128;
> int shifted = b >>> 4;
> shifted
268435448
> (byte) shifted
-8
你所需要的行为,可以使用 & 0xFF
将 byte
转换为 int
进行“无符号”转换:
> ((b & 0xFF) >>> 4)
8
有符号右移位运算符'>>'使用符号位来填充尾部位置,而无符号右移位运算符'>>'不使用符号位来填充尾部位置。它总是用0来填充尾部位置。