As I was using bit-shifting on byte, I notice I was getting weird results when using unsigned right shift (>>>). With int, both right shift (signed:>> and unsigned:>>>) behave as expected:  
    int min1 = Integer.MIN_VALUE>>31; //min1 = -1
    int min2 = Integer.MIN_VALUE>>>31; //min2 = 1
But when I do the same with byte, strange things happen with unsigned right shift:  
    byte b1 = Byte.MIN_VALUE; //b1 = -128
    b1 >>= 7; //b1 = -1
    byte b2 = Byte.MIN_VALUE; //b2 = -128
    b2 >>>= 7; //b2 = -1; NOT 1!
    b2 >>>= 8; //b2 = -1; NOT 0!
I figured that it could be that the compiler is converting the byte to int internally, but does not seem quite sufficient to explain that behaviour.  
Why is bit-shifting behaving that way with byte in Java?
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
                        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