Shift Operators
[Home] [Java] [HTML] [Tabs] [About Me] [Disclaimer] [All Downloads] [Contact]

 

This page has moved to a new location, click here !

I'll assume that you know what binary numbers are & that you are aware of the shift operators ( >> , << , >>>) in Java . If you'd like to know more about how , why , what of binary data mail me , I'll write a tutorial on it only if somebody needs it ! Do read the disclaimer at the end of this page before going further .

OK that said we can start with it .

Why byte is not a byte anymore after a shift operation ?

Lets assume the following block of code -
byte b = 2;
byte c = 1;
byte d = b >> c;

When the above code is compiled you get the following compile-time error -
Incompatible type for declaration. Explicit cast needed to convert int to byte.

The reason for this is that the operands ( b & c ) are implicitly promoted to the int type before any binary operators are applied . Refer JLS 5.6.1 .


What this means -
At the time of declaration/assignment 2 is defined as 00000010 ( byte type) .
But before the shift operand is applied , 2 is converted to 0000000000000000000000000000010 ( int type) .
And since there is no implicit conversion from int to byte , the error is justified .

The same is true for short & char types as well .

Before any binary operator is , applied arithmetic promotion of operands takes place so that the operands are at least of the type int .


What is shifting anyways ?

Shifting is basically taking the binary equivalent of a number & moving the bit pattern left or right . This is analogous to a queue - one bit moves forward & leaves while  the one behind takes it's place . Simple ! This is exactly what the >> & << operators do ( >>> is a bit tricky ) .


Try an example !

Consider 78 whose binary equivalent is
00000000 00000000 00000000 01001110 Try here !

Say you wanna shift it right ( >> ) 2 times , keeping that queue in mind , here's what we get
00000000 00000000 00000000 00010011 ( = 19 )

Similarly now lets shift left ( << ) 3 times & we get
00000000 00000000 00000010 01110000 ( = 624 )

Now for some negative values -
Lets try -65 whose binary equivalent is
11111111 11111111 11111111 10111111

Shift left ( << ) 2 times & the result is
11111111 11111111 11111110 11111100 ( = -260 )

Shift right ( >> ) 2 times & the result is
11111111 11111111 11111111 11101111 ( = -17 )


Did I miss something up there !?

When you shift left ( << ) the void left behind by the shift is filled by zero's but that's not the case when you shift right ( >> ) .


When shifting right ( >> ) the leftmost bits exposed by the right shift are filled in with previous contents of the leftmost bit . That's why when we right shifted 78 we filled it with zero's ( zero is the leftmost bit ) & when we right shifted -65 we filled it with one's ( since one was the leftmost bit ) .

As for the bits in the extreme right ( rightmost bits ) , they're discarded .

Try right shifting ( >> ) these values -
-1 = 11111111 11111111 11111111 11111111 ( result is always -1)
0 = 00000000 00000000 00000000 00000000 ( result is always 0)

Note that right shifting ( >> ) always preserves the sign of the original number i.e. to say that a negative number will stay negative while a positive number will stay positive after a right shift ( >> ) .


So what about the >>> ( unsigned right shift ) operator ?

Sometimes we may require a right shift ( >> ) but we wouldn't like it to fill one's , instead we'd like it to fill zero's & only zero's no matter what . This is where the >>> ( unsigned right shift ) operator fits in .

It fills the void left behind by the leftmost bits with zero's only . So -
78 >>> 2 = 19 &
-78 >>> 2 = 1073741804 Try here .


That's all about there is to shifting . Practice with some code samples to get a hang of the concept . The applet you tried up there is available for download .If you'd like to download the applet do read the disclaimer first !

 

Read Disclaimer
Download Applet .

[Home] [Java] [HTML] [Tabs] [About Me] [Disclaimer] [All Downloads] [Contact]