Saturday 30 December 2017

Bitwise Operators in C and C++ Programming

Bitwise Operators in C and C++ Programming Languages


Uses of Bitwise Operators and Why to Study Bitwise.

  1. Compression: Occasionally, you may want to implement a large number of Boolean variables, without using a lot of space. A 32-bit int can be used to store 32 Boolean variables. Normally, the minimum size for one Boolean variable is one byte. All types in C must have sizes that are multiples of bytes. However, only one bit is necessary to represent a Boolean value.
  2. Set operations: You can also use bits to represent elements of a (small) set. If a bit is 1, then element i is in the set, otherwise it's not. You can use bitwise AND to implement set intersection, bitwise OR to implement set union.
  3. Encryption: swapping the bits of a string for e.g. according to a predefined shared key will create an encrypted string.
& (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.
 
| (bitwise OR) Takes two numbers as operands and does OR on every bit of two numbers. The result of OR is 1 any of the two bits is 1.
 
^ (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.

 << (left shift) Takes two numbers, left shifts the bits of the first operand, the second operand decides the number of places to shift.

>> (right shift) Takes two numbers, right shifts the bits of the first operand, the second operand decides the number of places to shift.

~ (bitwise NOT) Takes one number and inverts all bits of it

Following is example C program.


 

Following are interesting facts about bitwise operators.

  • The left shift and right shift operators should not be used for negative numbers The result of is undefined behabiour if any of the operands is a negative number. 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 behaviour is undefined. For example, 1 << 33 is undefined if integers are stored using 32 bits. 
  •  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. For examples click here.
  •  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. 
int main() 

 int x = 2, y = 5;
 (x & y)? printf("True ") : printf("False ");
 (x && y)? printf("True ") : printf("False ");
 return 0; 

Output: 
False True

    • 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. 
    int main() 
    { int x = 19; 
     printf ("x << 1 = %d\n", x << 1); 
    printf ("x >> 1 = %d\n", x >> 1);
    return 0;
    }

    Output:
    38 9

    • 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.
    int main()
    {
    int x = 19;
    (x & 1)? printf("Odd"): printf("Even");
    return 0;
    }

    Output: Odd

    • <1 00001000="" b="" d="" is="" n="" printf="" result="" the=""><1 16="" b="">The ~ operator should be used carefully<1 00001000="" b="" d="" is="" n="" printf="" result="" the=""><1 16="" b="">. The result of ~ operator on a small number can be a big number if the result is stored in an unsigned variable. And result may be negative number if result is stored in signed variable (assuming that the negative numbers are stored in 2’s complement form where leftmost bit is the sign bit)
      <1 00001000="" b="" d="" is="" n="" printf="" result="" the=""><1 16="" b="">
    <1 00001000="" b="" d="" is="" n="" printf="" result="" the=""><1 16="" b=""> // Note that the output compiler dependent
    int main()
    {
    unsigned int x = 1;
    printf("SIgned %d \n", ~x);
    printf("Unsigned %ud \n", ~x);
    return 0;
    }


    Output:
    Signed Result -2
    Unsigned Result 24967294d */


    No comments:

    Post a Comment

    Thank you for your Time. Keep Learning

    Geeks4Coding

    Contributors

    Popular Posts