I have a byte variable:
byte varB = (byte) -1; // binary view: 1111 1111
I want to see the two left-most bits and do an unsigned right shift of 6 digits:
varB = (byte) (varB >>> 6);
But I'm getting -1 as if it was int type, and getting 3 only if I shift for 30!
How can I work around this and get the result only with a 6-digit shift?
The reason is the sign extension associated with the numeric promotion to int
that occurs when bit-shifting. The value varB
is promoted to int
before shifting. The unsigned bit-shift to the right does occur, but its effects are dropped when casting back to byte
, which only keeps the last 8 bits:
varB (byte) : 11111111
promoted to int : 11111111 11111111 11111111 11111111
shift right 6 : 00000011 11111111 11111111 11111111
cast to byte : 11111111
You can use the bitwise-and operator &
to mask out the unwanted bits before shifting. Bit-anding with 0xFF
keeps only the 8 least significant bits.
varB = (byte) ((varB & 0xFF) >>> 6);
Here's what happens now:
varB (byte) : 11111111
promoted to int : 11111111 11111111 11111111 11111111
bit-and mask : 00000000 00000000 00000000 11111111
shift right 6 : 00000000 00000000 00000000 00000011
cast to byte : 00000011
Because thats how shifting for bytes in java is defined in the language: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19.
The gist is that types smaller than int are silently widened to int, shifted and then narrowed back.
Which makes your single line effectively the equivalent of:
byte b = -1; // 1111_1111
int temp = b; // 1111_1111_1111_1111_1111_1111_1111_1111
temp >>>= 6; // 0000_0011_1111_1111_1111_1111_1111_1111
b = (byte) temp; // 1111_1111
To shift just the byte you need to make the widening conversion explicitly yourself with unsigned semantics (and the narrowing conversion needs to be manually, too):
byte b = -1; // 1111_1111
int temp = b & 0xFF; // 0000_0000_0000_0000_0000_0000_1111_1111
temp >>>= 6; // 0000_0000_0000_0000_0000_0000_0000_0011
b = (byte) temp; // 0000_0011
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With