Lesson 3.7. Shifting operators

In C, there are two operators for shifting bits:

s = a >> b;

We can see in the example above that these operators accept two operands, so they are binary operators. The first operand (a) is the variable to shift. The second operand is the number of bits of the shift. If b is 2, the variable a will be shifted by two bits to the right.

Example 1

Consider the following example:

unsigned char a= 0x3C;
printf ("a << 1 = %d\n", a<<1 );

To simulate the result of this operator, it is necessary to follow the same method as for bitwise operators. Let's start by converting the variable a into binary :

$$ (3C)_{16} = (0011\:1100)_2 $$

Now, let's shift the binary word to the left by 1 bit:

Shifting operator in C, shift one bit to the left.

$$ (0011\:1100)_2 << 1 = (0111\:1000)_2 $$

Note that the shift is not a circular permutation, the left bit (high order) does not return to the right bit. Here, the left bit is lost. With a left shift, the low-order bit (right-hand bit) is always replaced by a zero.

It is now enough to convert this result in base 10 to obtain the display of the program:

$$ (0111\:1000)_2 = (120)_{10} $$

Let's check this result:

Example 2

Let's consider the following example:

unsigned char a= 0x3C;
printf ("a >> 3 = %d\n", a>>3 );

The conversion of the variable a to binary is identical to the previous example.

$$ (3C)_{16} = (0011\:1100)_2 $$

The general scheme of the shift is represented by:

Shifting operator in C, shift three bits to the right.

$$ (0011\:1100)_2 >> 3 = (0000\:0111)_2 = (7)_{10}$$

Let's check this result:

Shifting and multiplying

A binary shift is the same as a multiplication or division. When we shift to the left, we multiply by two:

For right-hand shifts, if we omit the decimal part of the result, we can also consider that :

To guarantee equivalence between these multiplications and the shifts, the bit that is entered in the binary word is always a zero, unless the variable is negative.

As shifts are generally only used on unsigned, remember that in this case, zeros are always inserted.

Exercise

Complete the following program to perform two operations:

The results will be assigned to the variables shift and mult respectively.

#include <stdio.h>

int main(void) {
    unsigned char a=0x12;
    unsigned char mult, shift;

    // shift = a shifted 3 bits to the left
    // COMPLETE HERE

    // mult = a multiplied by 8
    // COMPLETE HERE

    // Display the results
    printf ("a << 3 = %d\n", shift);
    printf ("a * 8 = %d\n", mult);

    return 0;
}

Quiz

What does the following program display?

unsigned char a=3;
printf ("%d", a << 1 );
Check Bravo! $$ (0000\:0011)_2 << 1 = (0000\:0110)_2 = (6)_{10} $$ Try again...

What does the following program display?

unsigned char a=3;
printf ("%d", a >> 1 );
Check Bravo! $$ (0000\:0011)_2 >> 1 = (0000\:0001)_2 = (1)_{10} $$ Try again...

What does the following program display?

unsigned char a=0x0F;
printf ("%d", a << 4 );
Check Bravo! $$ (0000\:1111)_2 << 1 = (1111\:0000)_2 = (240)_{10} $$ Try again...

What does the following program display?

unsigned char a=0x0F;
printf ("%d", a >> 4 );
Check Bravo! $$ (0000\:1111)_2 >> 1 = (0000\:0000)_2 = (0)_{10} $$ Try again...

Without converting to binary, find what the following program displays.

unsigned char a=1;
printf ("%d", a << 5 );
Check Bravo! The shift is also a multiplication. The result is therefore \( a \times 2^{5} = a \times 32 \) Try again...

Without converting to binary, find what the following program displays.

unsigned char a=26;
printf ("%d", a >> 2 );
Check Bravo! The shift is also a division. The result is therefore \( \dfrac {a} {2^{2}} = 6 \) because we keep only the integer part. Try again...

Without converting to binary, find what the following program displays.

unsigned int a=0xA4D912AB;
printf ("%X", a << 4 );
Check Bravo ! In hexadecimal, each symbol is coded on 4 bits. As we shift 4 bits, we shift one symbol. Try again...

See also


Last update : 11/21/2022