Skip to main content
Engineering LibreTexts

4.13: Bitwise Operators

  • Page ID
    29045
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Bitwise Operators

    The thing about bitwise operators is they work at the bit level, and it takes some practice to get used to them.

    Table of C++ bitwise operators

    So, if we take 5 - we get the 4 bits 0101. 9 is the 4 bits 1001

    1. The & (bitwise AND) takes two numbers as operands and does AND on every bit of two numbers. The result of AND is 1 only if both bits are 1.
      To AND the bits - a 1 AND 1 is 1 - EVERYTHING else is 0.
      0101
      1001
      0001  - which is 1
    2. The | (bitwise OR)  takes two numbers as operands and does OR on every bit of two numbers. The result of OR is 1 if any of the two bits is 1.
      To OR the bits - a 1 OR 0 is 1 - only two 0's is 0.
      0101
      1001
      1101  - which is 13
    3. The ^ (bitwise XOR) takes two numbers as operands and does XOR on every bit of two numbers. The result of XOR is 1 if the two bits are different.
      To XOR the bits we find where the bits are different
      0101
      1001
      1100  - which is 12
    4. The << (left shift)  takes two numbers, left shifts the bits of the first operand, the second operand decides the number of places to shift.
      To shift we need to take an 8 bit number - 9 in 16 bits is 00001001. Shift it one bit to the left we get 00010010, which is w 18
    5. The >> (right shift)  takes two numbers, right shifts the bits of the first operand, the second operand decides the number of places to shift.
      To shift we need to take an 8 bit number - 9 in 16 bits is 00001001. Shift it one bit to the right we get 00000100, which is now 4
    6. The ~ (bitwise NOT) takes one number and inverts all bits of it. Take our 16 bit 5, 00000101 and invert every bit give us 11111010 which is 250

    The following code shows this.

    // C++ Program to demonstrate use of bitwise operators 
    #include <iostream> 
    using namespace std;
    
    int main()
    { 
        // a = 5(00000101), b = 9(00001001) 
        unsigned char a = 5, b = 9; 
         
        cout <<  "a = " << +a << " b = " << +b << endl; 
        
        //The result is 00000001
        cout << "a & b = " << (a & b) << endl; 
        
        // The result is 00001101 
        cout <<  "a | b =   " << (a | b) << endl; 
        
        // The result is 00001100 
        cout << "a^b =   " << (a ^ b) << endl; 
        
        // The result is 11111010 
        a = ~a;
        cout << "~a =   " << +a  << endl; 
        
        // The result is 00010010 
        cout << "b<<1 =   " << (b << 1) << endl; 
        
        // The result is 00000100 
        cout << "b>>1 =   " << (b >> 1) << endl; 
        
        return 0; 
    } 

     

    Output:

    a = 5 b = 9
    a & b = 1
    a | b =   13
    a^b =   12
    ~a =   250
    b<<1 =   18
    b>>1 =   4
    
    1. The left shift and right shift operators should not be used for negative numbers. If any of the operands is a negative number, it results in undefined behavior. For example results of both -1 << 1 and 1 << -1 is undefined. Also, if the number is shifted more than the size of integer, the behavior is undefined. For example, 1 << 33 is undefined if integers are stored using 32 bits. 
    2. The bitwise XOR operator is the most useful operator from technical interview perspective. It is used in many problems. A simple example could be “Given a set of numbers where all elements occur even number of times except one number, find the odd occurring number” This problem can be efficiently solved by just doing XOR of all numbers.
    3. The bitwise operators should not be used in place of logical operators. The result of logical operators (&&, || and !) is either 0 or 1, but bitwise operators return an integer value. Also, the logical operators consider any non-zero operand as 1. For example, consider the following program, the results of & and && are different for same operands.
    4. The left-shift and right-shift operators are equivalent to multiplication and division by 2 respectively. As mentioned in point 1, it works only if numbers are positive.
    5. The & operator can be used to quickly check if a number is odd or even. The value of expression (x & 1) would be non-zero only if x is odd, otherwise the value would be zero.
    6. The ~ operator should be used carefully. The result of ~ operator on a small number can be a big number if the result is stored in an unsigned variable. And the result may be a negative number if the result is stored in a signed variable (assuming that the negative numbers are stored in 2’s complement form where the leftmost bit is the sign bit)

    Adapted from:
    "Bitwise Operators in C/C++" by Multiple Contributors, Geeks for Geeks is licensed under CC BY-SA 4.0 


    This page titled 4.13: Bitwise Operators is shared under a CC BY-SA license and was authored, remixed, and/or curated by Patrick McClanahan.

    • Was this article helpful?