Behaviour of unsigned right shift applied to byte

2019-01-09 00:46发布

Consider the following snip of java code

byte b=(byte) 0xf1;
byte c=(byte)(b>>4);
byte d=(byte) (b>>>4);

output:

c=0xff
d=0xff

expected output:

c=0x0f

how? as b in binary 1111 0001 after unsigned right shift 0000 1111 hence 0x0f but why is it 0xff how?

4条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-09 01:30

The problem is that all arguments are first promoted to int before the shift operation takes place:

byte b = (byte) 0xf1;

b is signed, so its value is -15.

byte c = (byte) (b >> 4);

b is first sign-extended to the integer -15 = 0xfffffff1, then shifted right to 0xffffffff and truncated to 0xff by the cast to byte.

byte d = (byte) (b >>> 4);

b is first sign-extended to the integer -15 = 0xfffffff1, then shifted right to 0x0fffffff and truncated to 0xff by the cast to byte.

You can do (b & 0xff) >>> 4 to get the desired effect.

查看更多
Rolldiameter
3楼-- · 2019-01-09 01:41

According to Bitwise and Bit Shift Operators:

The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.

So with b >> 4 you transform 1111 0001 to 1111 1111 (b is negative, so it appends 1) which is 0xff.

查看更多
太酷不给撩
4楼-- · 2019-01-09 01:45

I'd guess that b is sign extended to int before shifting.

So this might work as expected:

(byte)((0x000000FF & b)>>4)
查看更多
该账号已被封号
5楼-- · 2019-01-09 01:49

Java tries to skimp on having explicit support for unsigned basic types by defining the two different shift operators instead.

The question talks about unsigned right shift, but the examples does both (signed and unsigned), and shows the value of the signed shift (>>).

Your calculations would be right for unsigned shift (>>>).

查看更多
登录 后发表回答