The left and right shift operators are the last two bitwise operators for us to look at.
In C (and C++), << and >> are used to shift bits around inside bytes. Not just in any random fashion – these operators move all the bits either to the left or to the right, exactly as their names imply.
Left bit shift
This is the easy one. No matter what your integer type (long, short, signed, unsigned), applying this operator always moves the bits to the left and pads with zeros from the right. The bits that move off to the left are discarded – they are gone forever and you can’t get them back.
For each place that the bits are shifted, it is the equivalent of multiplying by 2.
62 << 2 = 248 //or, multiply by 4
0011 1110 //62
(00)1111 1000 // 248 (discarded) padded
The next example shows what happens if you use an integer that is not large enough to hold the result. 120 << 2 should give you 480, but since we are using a single byte, we lose bits from the left and the result is 224:
120 << 2 = 224
0111 1000 //120
(01)1110 0000 // 224 (discarded) padded
Right bit shift
The right shift does the opposite of the left shift. If you are applying it to an unsigned integer this is always the case and it is always the equivalent of dividing by 2 for each place shifted (and it always rounds down towards zero).
62 >> 2 = 15 // or, divide by 4
0011 1110 //62
0000 1111(10) // 15 padded (discarded)
Right shifting signed integers
If you apply a right shift to a signed integer, then the result may vary. On some machines, under some compilers, it will pad with sign bits, i.e. 1s for a negative number and 0s for a positive number, since the leftmost bit is the sign bit for signed integers. This is also termed the ‘arithmetic shift’. On other machines, with other compilers, it will always pad with zeros. This is termed the ‘logical shift’.
GCC, which is the compiler I use, implements the arithmetic shift. You can easily write a few lines of code to test out what your own compiler does if you can’t find details in the documentation.
Note that right shifting a negative signed integer rounds towards negative infinity, not zero. -50 >> 2 will give -13, but -50 / 4 will give -12.
Two’s complement is used to represent signed integers, so the binary representation for the negative numbers below is probably not familiar. However, you can still see how the shift is applied here. (I’d like to cover two’s complement representation at some point in the future – it requires its own post to be explained effectively.)
1100 1110 // -50
1111 0011(10) // -13 padded (discarded)
What would I use bit shifting for?
We’ll take a look at some examples next week – right now I have a 3 week old baby that needs feeding!