Andros Yang Andros Yang - 8 days ago 3
Java Question

Java bit wise operator (zero fill shift) not filling with zeros

I've been getting a weird problem with Java, and have tested on both a Windows and Mac system and have this problem come up consistently.

Take a look at this code

int a = -32; //11100000 as per two's complement
System.out.println(a >>> 2);


I expect this code to produce 56, which is 00111000 in its binary form. However, it produces the value 1073741816, 111111111111111111111111111000 in its binary form. I understand ints are 32-bits in java, but setting the type of byte also does the same thing.

However if I declare a binary literal like this

int b = 0b11100000;
System.out.println(b);
System.out.println(b >>> 2);


The first statement produces the value 224 (expected -32), while the second statement produces the expected value of 56

Am I going insane?

Answer

Your bit pattern in b is not 11100000 like you say, but 11111111 11111111 11111111 11100000

You're using an int which is 32 bits - not a byte - and using binary literals doesn't change that.

Even if you used byte rather than int it wouldn't fix your problem, because the Java bitshift operators first promote any type less than 32 bits to 32 bits.

So the resulting bit pattern is 00111111 11111111 11111111 11111000 after the shift.

If you want to mimic working with an 8-bit value, you need to bit-mask the 32-bit value to the lower 8 bits before applying the bitshift (you may as well use >> rather than >>> now)

System.out.println((b & 0xff) >>> 2);