Java has 2 bitshift operators for right shifts:
>> shifts right, and is dependant on the sign bit for the sign of the result
>>> shifts right and shifts a zero into leftmost bits
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html
This seems fairly simple, so can anyone explain to me why this code, when given a value of -128 for bar, produces a value of -2 for foo:
byte foo = (byte)((bar & ((byte)-64)) >>> 6);
What this is meant to do is take an 8bit byte, mask of the leftmost 2 bits, and shift them into the rightmost 2 bits. Ie:
initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b10000000
0b10000000 >>> 6 = 0b00000010
The result actually is -2, which is
0b11111110
Ie. 1s rather than zeros are shifted into left positions
It’s because the & is actually performing promotion to
int– which leaves an awful lot of “1” bits. You’re then shifting right, leaving the leftmost 2 bits as 0, but then ignoring those leftmost bits by casting back to byte.This becomes clearer when you separate out the operations:
prints
So to do your bit arithmetic again:
Even if you get the right result out of the & operation (by casting at that point),
>>>will promote the first operand tointfirst anyway.EDIT: The solution is to change how you mask things. Instead of masking by -64, mask by just 128+64=192=0xc0 instead:
That way you really only get left with the two bits you want, instead of having a load of 1s in the most significant 24 bits.