The Unsigned Right Shift

 The Unsigned Right Shift              As you have just seen, the >> operator automatically fills the high-order bit with its previous contents each time a shift occurs. This preserves the sign of the value. However, sometimes this is undesirable. For example, if you are shifting something that does not represent a numeric value, you may not want sign extension to take place. This situation is common when you are working with pixel-based values and graphics. In these cases you will generally want to shift a zero into the high-order bit no matter what its initial value was. This is known as an unsigned shift. To accomplish this, you will use java’s unsigned, shift-right operator,>>>, which always shifts zeros into the high-order bit.              The following code fragment demonstrates the >>>. Here, a is set to –1, which sets all 32 bits to 1 in binary. This value is then shifted right 24 bits, filling the top 24 bits with zeros, ignoring normal sign extension. This sets a to 255.              int a = -1;      a = a >>> 24;              Here is the same operation in binary form to further illustrate what is happening:              11111111 11111111 11111111 11111111            -1 in binary as an int             >>>24             00000000 00000000 00000000 00000000            255 in binary as an int              The >>> operator is often not as useful as you might like, since it is only meaningful for 32- and 64-bit values. Remember, smaller values are automatically promoted to int in expressions. This means that sign-extension occurs and that the shift will take place on a 32-bit rather than on an 8- or 16-bit value. That is, one might expect an unsigned right shift on a byte value to zero-fill beginning at bit 7. but this is not the case, since it is a 32-bit value that is actually being shifted. The following program demonstrates this effect:  // Unsigned shifting a byte value class ByteUShift {      static public void main(String args[]) {           char hex[] = {                                        ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’                };                byte b = (byte) 0xf1;                byte c = (byte) (b >> 4);                byte d = (byte) (b >> > 4);                byte e = (byte) ((b & 0xff) >> 4);        System.out.println(“     b = 0x” + hex [ (b >> 4) & 0x0f] + hex [b & 0x0f]);      System.out.println(“     b >> 4 = 0x” + hex [ (c >> 4) & 0x0f] + hex [c & 0x0f]);      System.out.println(“     b >>>4 = 0x” + hex [ (d >> 4) & 0x0f] + hex [d & 0x0f]);      System.out.println(“     (b&0xff) >> 4  = 0x” + hex [ (e >> 4) & 0x0f] + hex [e & 0x0f]);        } }               the following output of this program shows how the  >>> operator appears to do nothing when dealing with bytes. The variable b is set to an arbitrary negative byte value for this demonstration. Then c is assigned the byte value of b shifted right by four, which is 0xff because of the expected sign extension. Then d is assigned the byte value of b is unsigned shifted right by four, which you might have expected to be 0x0f, but is actually 0xff because of the sign extension that happened when b was promoted to int before the shift. The last expression sets e to the byte value of b masked to 8 bits using the AND operator, then the unsigned shift right operator was not used for d, since the state of the sign bit after the AND was known.                                 b = 0xf1                    b >> 4 = 0xff              b >>> 4 = 0xff           (b & 0xff) >> 4 = 0x0f