Programming Tutorials

The Unsigned Right Shift

By: aathishankaran in Java Tutorials on 2007-02-06  

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





Add Comment

* Required information
1000

Comments

No comments yet. Be the first!

Most Viewed Articles (in Java )

Latest Articles (in Java)