考虑以下Java代码片段
byte b=(byte) 0xf1;
byte c=(byte)(b>>4);
byte d=(byte) (b>>>4);
Run Code Online (Sandbox Code Playgroud)
输出:
c=0xff
d=0xff
Run Code Online (Sandbox Code Playgroud)
预期产量:
c=0x0f
Run Code Online (Sandbox Code Playgroud)
怎么样?为b二进制1111 0001
无符号右移之后0000 1111,因此0x0f,但为什么是0xff 怎么了?
sta*_*lue 39
问题是所有参数int在转换操作发生之前首先被提升:
byte b = (byte) 0xf1;
Run Code Online (Sandbox Code Playgroud)
b 已签名,因此其值为-15.
byte c = (byte) (b >> 4);
Run Code Online (Sandbox Code Playgroud)
b是第一符号扩展到整数-15 = 0xfffffff1,那么右移到0xffffffff并截断为0xff通过浇铸到byte.
byte d = (byte) (b >>> 4);
Run Code Online (Sandbox Code Playgroud)
b是第一符号扩展到整数-15 = 0xfffffff1,那么右移到0x0fffffff并截断为0xff通过浇铸到byte.
你可以做到(b & 0xff) >>> 4达到预期的效果.
我想这b是int转移之前的符号扩展。
因此,这可能会按预期工作:
(byte)((0x000000FF & b)>>4)
Run Code Online (Sandbox Code Playgroud)