Weird behaviour of bit-shifting with byte in Java

ぃ、小莉子 提交于 2019-12-01 18:55:24

This happens exactly because byte is promoted to int prior performing bitwise operations. int -128 is presented as:

11111111 11111111 11111111 10000000

Thus, shifting right to 7 or 8 bits still leaves 7-th bit 1, so result is narrowed to negative byte value.

Compare:

System.out.println((byte) (b >>> 7));           // -1
System.out.println((byte) ((b & 0xFF) >>> 7));  //  1

By b & 0xFF, all highest bits are cleared prior shift, so result is produced as expected.

Shift operators for byte, short and char are always done on int.

Therefore, the value really being shifted is the int value -128, which looks like this

int b = 0b11111111_11111111_11111111_10000000;

When you do b2 >>= 7; what you are really doing is shifting the above value 7 places to the right, then casting back to a byte by only considering the last 8 bits.

After shifting 7 places to the right we get

        0b11111111_11111111_11111111_11111111;

When we convert this back to a byte, we get just 11111111, which is -1, because the byte type is signed.

If you want to get the answer 1 you could shift 31 places without sign extension.

byte b2 = Byte.MIN_VALUE; //b2 = -128
b2 >>>= 31;
System.out.println(b2);   // 1

Refer to JLS 15.19 Shift Operators:

Unary numeric promotion (§5.6.1) is performed on each operand separately.

and in 5.6.1 Unary Numeric Promotion :

if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion

So, your byte operands are promoted to int before shifting. The value -128 is 11111111111111111111111110000000 .

After the shifting 7 or 8 times, the lowest 8 bits are all 1s, which when assigning to a byte, a narrowing primitive conversion occurs. Refer to JLS 5.1.3 Narrowing Primitive Conversion :

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!