The Unsigned Right Shift

By: aathishankaran Viewed: 148 times  Printer Friendly Format    


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

 



Most Viewed Articles (in Java )

Latest Articles (in Java)

Comment on this tutorial