[advanced analysis of C language] 16 Analysis of bitwise operators in C language

Posted by shivabharat on Wed, 09 Mar 2022 04:10:52 +0100

Article catalogue

1, Bitwise operator analysis

2, Tips

3, Bit operation and logic operation

4, Summary

1, Bitwise operator analysis

  • Bitwise operators in C language

Bit operators directly operate on bit bits, which is the most efficient.

&Bitwise AND
|Bitwise OR
^Bitwise XOR
~Reverse
<<Shift left
>>Shift right
  • Move left and right attention points
    • Left operand must be of integer type
      • char and short are implicitly converted to int and then shifted
    • The range of right operand must be: [0,31]
    • Shift left operator < < shifts the binary bit of the operand to the left
      • Rule: discard the high order and make up 0 for the low order
    • Shift right operator > > shifts the binary bit of the operand to the right
      • Rule: the high bit is used to fill the symbol bit, and the low bit is discarded

The following code:

#include <stdio.h>

int main()
{
    printf("%d\n", 3 << 2); 
    printf("%d\n", 3 >> 1); 
    printf("%d\n", -1 >> 1); 
    printf("%d\n", 0x01 << 2 + 3);
    
    printf("%d\n", 3 << -1); // oops!
    
    return 0;
}

The following is the output result:

Note that the priority of four operations is greater than that of bit operations, so the result of 0x01 < < 2 + 3 is 32. Also, the range of the right operand must be: [0,31]. If it is not within this range, the output result of the program is determined by different types of compilers, and the result will be uncertain, just like 3 < < - 1 in this code.

2, Tips

  • Error proofing criteria:
    • Avoid bitwise operators, logical operators and mathematical operators appearing in the same expression at the same time
    • When bit operators, logical operators and mathematical operators need to participate in the operation at the same time, try to use parentheses () to express the calculation order
  • Tips:
    • Shifting n bits to the left is equivalent to multiplying 2 to the nth power, but the efficiency is higher than that of mathematical operators
    • Shifting n bits to the right is equivalent to dividing by 2 to the nth power, but it is more efficient than mathematical operators

Here is a code for exchanging the values of two integer variables:

#include <stdio.h>

#define SWAP1(a,b)  \
{                   \
    int t = a;      \
    a = b;          \
    b = t;          \
}    

#define SWAP2(a,b)  \
{                   \
    a = a + b;      \
    b = a - b;      \
    a = a - b;      \
}     

#define SWAP3(a,b)  \
{                   \
    a = a ^ b;      \
    b = a ^ b;      \
    a = a ^ b;      \
}   

int main()   
{
    int a = 1;
    int b = 2;
    
    //printf("a = %d\n", a);
    //printf("b = %d\n", b);
    
    SWAP1(a,b);
    
    printf("a = %d\n", a);
    printf("b = %d\n\n", b);
    
    a = 1;
    b = 2;
    
    SWAP2(a,b);
    
    printf("a = %d\n", a);
    printf("b = %d\n\n", b);
    
    a = 1;
    b = 2;
    SWAP3(a,b);
    
    printf("a = %d\n", a);
    printf("b = %d\n\n", b);   
    
    return 0;
}                                                                           

The first method needs to introduce third-party variables. The second method may lead to boundary crossing problems. The third method is more efficient and does not need to introduce third-party variables.

Note the third method: execute a = a ^ b; After, b = a ^ b; It is equivalent to b = a ^ b ^ b; First calculate the following, that is, b = a ^ 0, and the result is b = a; Then execute a = a ^ b; Equivalent to a = a ^ b ^ b, i.e. a = a ^ b ^ a, obviously the result is B.

Tips:

A XOR 0 equals a and a XOR 1 equals non-a.

3, Bit operation and logic operation

  • Bit operation is different from logical operation:
    • There is no short-circuit rule for bit operation, and each operand participates in the operation
    • The result of a bit operation is an integer, not 0 or 1
    • Bit operation priority is higher than logic operation priority

Here's another judgment condition for confusing change:

#include <stdio.h>

int main()
{
    int i = 0;
    int j = 0;
    int k = 0;
    
    if( ++i | ++j & ++k )
    {
        printf("Run here...\n");
    }
    
    printf("i = %d, j = %d, k = %d\n\n", i, j, k);
    
    i = 0;
    j = 0;
    k = 0;
    
     if( ++i || ++j && ++k )
    {
        printf("Run here...\n");
    }
    
    printf("i = %d, j = %d, k = %d\n\n", i, j, k);
    
    return 0;
}

The following is the output result:

It can be seen that if + + I | + + J & & + + k is wrongly written as + + I | + + J & + K, although they can run, the execution details are different, and bug s may appear in the actual project, which is not easy to check.

4, Summary

  • Bitwise operators can only be used with integer types
  • The range of right operands for shift left and shift right operators must be [0, 31]
  • There is no short circuit rule for bit operations, and all operands are evaluated
  • The efficiency of bit operation is higher than that of four operations and logic operation
  • Operation priority: four operation > bit operation > logic operation
     

Topics: C