One problem with the top answer is that, although it works correctly for unsigned >>>
right shift, it doesn't for signed >>
right shift. This is because >>
depends on the sign bit (the one farthest to the left) which moves when it's promoted to int
. This means when you use >>
, you'll get 00000011
when you might expect 11111111
. If you want a trick that works for both, try shifting left by 24, doing your chosen right shift, then shifting back to the right by 24. That way your byte data's sign bit is in the right place.
varB = (byte) (varB << 24 >> 6 >> 24);
I've [bracketed] the sign bit. Here's what's happening:
varB (byte) : [1]1111111
promoted to int : [1]1111111 11111111 11111111 11111111
shift left 24 : [1]1111111 00000000 00000000 00000000
signed shift right 6 : [1]1111111 11111100 00000000 00000000
shift right 24 : [1]1111111 11111111 11111111 11111111
cast to byte : [1]1111111
Here you can see it also works for >>>
:
varB = (byte) (varB << 24 >>> 6 >> 24);
varB (byte) : [1]1111111
promoted to int : [1]1111111 11111111 11111111 11111111
shift left 24 : [1]1111111 00000000 00000000 00000000
unsigned shift right 6 : [0]0000011 11111100 00000000 00000000
shift right 24 : [0]0000000 00000000 00000000 00000011
cast to byte : [0]0000011
This costs more operations for the convenience of not having to remember the rules about which one you should and shouldn't bitmask. So use whatever solution works for you.
Btw, it's good to know that short
is also promoted to int which means everything in these answers applies to it as well. The only difference is that you shift left/right by 16, and the bitmask is 0xFFFF
.
char
,byte
orshort
promote toint
first. – Thermopile