Shift operations

  • There are 2 kinds of shift operations:

    • Logical shift operation:

      • Considers the binary number as an unsigned number (i.e.: uses the binary number system)

    • Arithmetic shift operation:

      • Considers the binary number as an signed number (i.e.: uses the 2s complement code)


  • Recall that:

       Bin num       Unsigned (bin num syst)     Signed (2s compl code)
      ----------------------------------------------------------------
       11111110             254 (=2x(127))             -2 (= 2x(-1))
       11111111                                        -1 
       01111111             127
    

Logical/Arithmetic shifting a bit pattern to left

  • Logical/Arithmetic shifting one bit poistion to the left:

      • A 0 bit is always shifted into the open (empty) spot on the right

      • The left most bit of the bit pattern is lost

  • Example: shift the following bit pattern to left over 1 bit position:

           +---+---+---+---+---+---+---+---+
       x = | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
           +---+---+---+---+---+---+---+---+   
                    <------ shift left  

  • Result:

           +---+---+---+---+---+---+---+---+
       x = | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
           +---+---+---+---+---+---+---+---+    

Logical shifting a bit pattern to right

  • Logical shifting one bit poistion to the right:

      • A 0 bit is always shifted into the open (empty) spot on the left

      • The right most bit of the bit pattern is lost

  • Example: shift a bit pattern to right over 1 bit position with logical shift operation:

           +---+---+---+---+---+---+---+---+
       x = | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
           +---+---+---+---+---+---+---+---+  
               logical shift right ----->  

  • The logical shift of this bit pattern to the right over 1 bit position will result in:

           +---+---+---+---+---+---+---+---+
       x = | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
           +---+---+---+---+---+---+---+---+    

Arithmetic shifting a bit pattern to right   - part 1

  • Arithmetic shifting one bit poistion to the right:

      • The sign bit (= left most bit) is always shifted into the open (empty) spot

      • The right most bit of the bit pattern is lost

  • Suppose a byte size variable x contains the following bit pattern:

           +---+---+---+---+---+---+---+---+
       x = | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
           +---+---+---+---+---+---+---+---+  
             arithmetic shift right ----->  

  • The arithmetic shift of this bit pattern to the right over 1 bit position will result in:

           +---+---+---+---+---+---+---+---+
       x = | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
           +---+---+---+---+---+---+---+---+    

  • The arithmetic shift operation will preserve the sign of a 2s complement code

Arithmetic shifting a bit pattern to right   - part 2

  • Arithmetic shifting one bit poistion to the right:

      • The sign bit (= left most bit) is always shifted into the open (empty) spot

      • The right most bit of the bit pattern is lost

  • Suppose a byte size variable x contains the following bit pattern:

           +---+---+---+---+---+---+---+---+
       x = | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
           +---+---+---+---+---+---+---+---+  
             arithmetic shift right ----->  

  • The arithmetic shift of this bit pattern to the right over 1 bit position will result in:

           +---+---+---+---+---+---+---+---+
       x = | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 |
           +---+---+---+---+---+---+---+---+    

  • The arithmetic shift operation will preserve the sign of a 2s complement code

The (bitwise) shift operators of C

  • The shift operators in C are:

      <<       shift left
      >>       shift right  

  • Syntax (how to use them):

      x << n    shift the bit pattern in x left  over n bit positions
    
      x >> n    shift the bit pattern in x right over n bit positions
    
                if x is an unsigned data type, use a logical shift
    	    if x is an signed data type,   use a arithmetic shift
    

The (bitwise) shift operators of C   Example C program

int main( int argc, char* argv[] )
{
     unsigned char a0 = 0b01001100;   
     unsigned char a1 = 0b11001100;
     signed   char b0 = 0b01001100;
     signed   char b1 = 0b11001100;

     printf("Left shifts:\n");
     printf("  unsigned: "); printBits8(a0); printBits8(a0 << 1); printf("\n");
     printf("            "); printBits8(a1); printBits8(a1 << 1); printf("\n");
     printf("    signed: "); printBits8(b0); printBits8(b0 << 1); printf("\n");
     printf("            "); printBits8(b1); printBits8(b1 << 1); printf("\n");

     printf("\nRight shifts:\n");
     printf("  unsigned: "); printBits8(a0); printBits8(a0 >> 1); printf("\n");
     printf("            "); printBits8(a1); printBits8(a1 >> 1); printf("\n");
     printf("    signed: "); printBits8(b0); printBits8(b0 >> 1); printf("\n");
     printf("            "); printBits8(b1); printBits8(b1 >> 1); printf("\n");
}

DEMO: demo/C/set1/shift1.c

Left/right shift 1 bit position ≡ multiply/divide by 2 in binary

  • Shift left by one bit multiply a binary number by 2

    Example:

       Bit pattern | Value in decimal   Left shift 1 bit | Value in decimal
      -------------+-----------------   -----------------+-----------------
        00000011   |       3       --->    00000110      |     6 (=3x2)
        00000101   |       5       --->    00001010	     |    10 (=5x2)  

  • Shift right by one bit divide a binary number by 2 (= find quotient)

    Example:

       Bit pattern| Value in decimal   Right shift 1 bit | Value in decimal
      -------------+-----------------   -----------------+-----------------
        00000110   |       6               00000011      |     3 (= 6%2)
        00000011   |       3               00000001      |     1 (= 3%2)
        00000101   |       5               00000010	     |     2 (= 5%2) 

  • Note:

    • The result is invalid when there is an overflow (obviously)

Final note

 

  • It should not be surprising that:

      shift left  1 position  ≡  multiply by 2 in binary
      shift right 1 position  ≡  divide   by 2 in binary 

  • It is based on the same principle as in decimal:

      shift left  1 position  ≡  multiply by 10 in decimal
      shift right 1 position  ≡  divide   by 10 in decimal 

    Example:

     Decimal number = 12    Shift left:  120    ≡  12×10
     Decimal number = 120   Shift right: 12     ≡  120/10