byte
data type is based on Two's complement binary signed number representation with a value range from -128 to +127.
Positive values from 0 to 127 have it's most significant bit equal to 0 representing +
.
Here binary representation is the same as it's numeric value, for example byte 00000100 = int 4
Negative values from -128 to -1 have it's most significant bit equal to 1 representing -
However in negative range, Two's complement binary representation is NOT the same as it's numeric value, for example you would expect byte 10000100
to be equal to int 132
, but is actually -124
.
Simply casting a byte
to int
won't help.
Casting just widens 1 byte to 4 btytes, 10000100 ==> 11111111111111111111111110000100
which is equal to -124, not 132, because int
data type is also based on Two's complement. Casting byte
into int
is a step in the right direction, however you also need to get rid of all these ones in front. 255&b[i]
trick achieves that.
This is what happens in 255&b[i]
:
According to conversion rules defined in the the JLS &
bitwise operator first converts it's operands to int, which means 255&b[i]
is the same as ((int)255)&((int)b[i])
. When byte is cast to int it just gets wider:
10000100 = byte -124 ==> 11111111111111111111111110000100 = int -124
Then bitwise AND is performed.
11111111111111111111111110000100 = int -124
&
00000000000000000000000011111111 = int 255
--------------------------------
00000000000000000000000010000100 = int 132
Final result is an int 132