In the previous part of the tutorial I introduced the logical bitwise operators, describing how these operators could be used to extract and modify individual bits within an integer. The bitwise operator set is complete once the shift operators are understood.
Shift Left Operator
The shift operators allow programmers to adjust an integer by shifting all of its bits to the left or the right. The following diagram shows the affect of shifting a value to the left by one digit.
00001111 = 15
00011110 = 30
As you can see, each bit is moved to the left and the lowest order bit becomes zero. As this is a binary operation, the effect of shifting to the left is to double the value. In fact, this method is often used to perform some multiplication as it can be faster than using arithmetic multiplication.
In C#, the shift left operator is represented as two less than signs (<<). The operator can be used to shift the binary number by one or more digits. The number of digits is specified after the operator, as in the following code:
uint value = 15; // 00001111
uint doubled = value << 1; // Result = 00011110 = 30
uint shiftFour = value << 4; // Result = 11110000 = 240
Shift Right Operator
The shift right operator provides the reverse of shift left, moving each bit to the right by a number of digits. C# uses two greater than signs (>>) for the operator.
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
When using either shift function, one bit, called the overflow bit, will be shifted outside of the binary value. The value of this digit is lost during the operation and cannot be recovered. Should the value of the bit be important then it should be tested before the shifting using a logical bitwise operator. The loss overflow data is important if the shift operations are being used for multiplication or division to ensure the correct result:
uint value = 15; // 00001111
uint halved = value >> 1; // Result = 00000111 = 7
As indicated in a previous article, signed integers use the highest order bit to determine if a value is positive or negative and that the remaining bits use two's complement notation for negative values The highest order bit would normally be considered as the overflow bit for a shift left operation. To allow for this, C# ignores the bit for signed data types and shifts negative values accordingly. Thus shifting works for positive and negative values.
int value = -240;
int halved = value >> 1; // Result = -120
Compound Assignment Operators
The shift operators have equivalents for compound assignment similar to other operators discussed in this tutorial. These are used by adding an equals sign to the operator and using the number of bits to shift by as the operand. The following example demonstrates their use:
int value = 240;
value >>= 2; // Result = 60
value <<= 1; // Result = 120
We can now extend the operator precedence table with the shift operators.
|Increment / Decrement Operators|
|++(postfix) --(postfix) ++(prefix) --(prefix)|
|Basic Arithmetic Operators|
|* / % + -|
|Bitwise Shift Operators|
|Logic / Bitwise Operators|
|& ^ | && |||
|Compound Assignment Operators|
|*= /= %= += -= >>= <<= &= ^= |=|
14 September 2006