842Mono
842Mono

Reputation: 1988

Logical and Arithmetic shift's output

Here's a tiny java program

public class otherclass {
public static void main(String[]args){
        byte a=-5;

        byte d= (byte) (a>>>1);
        System.out.println(d);
        byte e= (byte) (a>>>2);
        System.out.println(e);
        byte f= (byte) (a>>1);
        System.out.println(f);
        byte g= (byte) (a>>2);
        System.out.println(g);
}
}

output:

-3
-2
-3
-2

The second two outputs (those -3 and -2 of the logical shifts) I understand.

negative 5 is 11111011

arithmetic shift shifts to the right and the extra added bit on the left is like the MSB. So one shift makes 11111101 which is negative 3. Negative two is also fine.

The logical shift is supposed to add zeros to the left. 11111011 should become 01111101 which is 125. How does it also output negative 3?

Upvotes: 0

Views: 105

Answers (1)

rgettman
rgettman

Reputation: 178263

The missing piece of information is that Java promotes the values to int when bit-shifting them, called binary numeric promotion. The byte values are promoted to int before they are shifted, then the shift occurs, then they are cast back to byte.

-5 as byte  : 11111011
-5 as int   : 11111111 11111111 11111111 11111011
Bit shifted : 01111111 11111111 11111111 11111101

The zero is shifted in, but the cast back to byte discards it all but the last 8 bits anyway.

Cast to byte: 11111101 (-3)

If you would like the >>> operation to behave as if there were no binary numeric promotion, then you must mask out the final 8 bits from the promoted int.

byte d= (byte) ((a & 0xFF)>>>1);
System.out.println(d);
byte e= (byte) ((a & 0xFF)>>>2);
System.out.println(e);

Output:

125
62

What's happening here:

-5 as byte  : 11111011
-5 as int   : 11111111 11111111 11111111 11111011
Bit masked  : 00000000 00000000 00000000 11111011
Bit shifted : 00000000 00000000 00000000 01111101

The zero is shifted in as before, but the cast back to byte discards it all but the last 8 bits anyway.

Cast to byte: 01111101 (125)

Note that this would occur with >>> and with >>, so only do the bit-and with 0xFF on the >>> operations.

Upvotes: 4

Related Questions