 .NET 1.1C# Bitwise Shift Operators
The tenth part of the C# Fundamentals tutorial continues consideration of the C# bitwise operators by introducing the shift functions. These operators extend C#'s capabilities for processing binary information.
Introduction
In the previous part of the C# Fundamentals tutorial I introduced the logical C# bitwise operators. The article described how the bitwise operators could be used to identify and modify the values of individual bits within an integer representation of a binary number. The bitwise operator set is complete once the shift operators are understood.
Shift Left Operator
The shift operators are simple in nature. They allow the programmer to adjust the binary number by shifting all of the individual bits of an integer value to the left or the right. The following diagram shows the affect of shifting a value to the left by a single digit.
00001111 = 15
SHIFT LEFT
00011110 = 30
As you can see from the above example, each bit is moved to the left and the lowest order bit receives a zero. As this is a binary operation, the affect of shifting to the left is to double the integer value. In fact, this method is often used to perform simple multiplication as it is faster and more efficient than using arithmetic multiplication.
In the C# programming language, 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 indicated after the operator. The following example illustrates this:
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 the shift left operator, moving each bit to the right by a number of digits. In the C# programming language, the shift right operator is represented as two greater than signs (>>).
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
Overflow Bits
When using either the left or right shifting functions, one bit will be shifted outside of the binary value. This bit is sometimes called the overflow bit. The value of this binary digit is lost during the operation and it is not possible to recover it. Should the value of the bit be important then it should be tested before the shift procedure using one of the logical bitwise functions. The loss of overflow data is important if the shift operations are being used for multiplication or division as this can produce misleading results as shown below:
uint value = 15; // 00001111
uint halved = value >> 1; // Result = 00000111 = 7
Signed Integers
As indicated in a previous part of the C# Fundamentals tutorial, signed integers use the highest order bit to determine if the value of a variable 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# understands that this bit should not be adjusted for signed data types and that negative numbers should be shifted accordingly. Thus shifting works for negative values as well as positive ones.
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 earlier parts of this tutorial. These are used by adding an equals sign to the relevant 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
Operator Precedence
We can now extend the operator precedence table further using the new operators discussed in this article.
| Parentheses Operator |
|---|
| () | | Increment / Decrement Operators |
|---|
| ++(postfix) --(postfix) ++(prefix) --(prefix) | | Complement Operators |
|---|
| ! ~ | | Basic Arithmetic Operators |
|---|
| * / % + - | | Bitwise Shift Operators |
|---|
| << >> | | Equivalence Operators |
|---|
| == != | | Logic / Bitwise Operators |
|---|
| & ^ | && || | | Assignment Operator |
|---|
| = | | Compound Assignment Operators |
|---|
| *= /= %= += -= >>= <<= &= ^= |= |
|