jbu jbu - 3 months ago 21
Java Question

java bit manipulation

byte x = -1;
for(int i = 0; i < 8; i++)
{
x = (byte) (x >>> 1);
System.out.println("X: " + x);
}


As I understand it, java stores data in two's-complement, meaning -1 = 11111111 (according to wikipedia).

Also, from the java docs:
"The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension. "

Which means that >>> would shift a 0 to the left most bit every time. So I expect this code to be

iteration: bit representation of x

0: 11111111

1: 01111111

2: 00111111

3: 00011111

...so on

However, my output is always X: -1, meaning (I guess) that >>> is putting the sign bit in the left most position. So I then try >>, and same result.

What's going on? I would expect my output to be: X: -1, x: 127, x: 63, etc.

Answer

Whoever thought that bytes should be signed when Java was invented should be taken out and beaten with a wet stick of celery until they cry :-)

You can do what you want by casting up to an int and ensuring you never shift a 1 into the top bit, something like this:

byte x = -1;
int x2 = ((int)x) & 0xff;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X: " + x2);
}

Your particular problem is because >>> is casting up to an int to do the shift, then you're casting it back to a byte, as shown here:

byte x = -1;
int x2 = ((int)x) & 0xff;
int x3;
int x4 = x2;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X2: " + x2);
    x3 = (x >>> 1);
    x = (byte)x3;
    x4 = (x4 >>> 1);
    System.out.println("X: " + x3 + " " + x + " " + x4);
}

Which outputs:

X2: 127
X: 2147483647 -1 127
X2: 63
X: 2147483647 -1 63
X2: 31
X: 2147483647 -1 31
X2: 15
X: 2147483647 -1 15
X2: 7
X: 2147483647 -1 7
X2: 3
X: 2147483647 -1 3
X2: 1
X: 2147483647 -1 1
X2: 0
X: 2147483647 -1 0

You can clearly see that x and x3 don't work (even though x3 shifts correctly, casting it back to byte in x sets it to -1 again). x4 works perfectly.

Comments