C language, explain binary bit operation in detail

This article mainly explains the bit operation of integers, for your reference


foreword

Recently, I am very interested in binary operations. After consulting a lot of information and writing a demo, I have a certain understanding of bit operations. I will record this study here.


1. Bit operation

Data is stored in binary numbers inside the computer, so the use of bit operations can speed up the efficiency of program operation

These integers are stored using two's complement notation, for example

Positive number 3 Original code 0011 Inverse code 0011 Complement code 0011

Negative number -3 Original code 1011 Inverse code 1100 Complement code 1101

2. Reconciliation

3. Operation

4. Function operation 

1. Exchange of two numbers 

 Of course, the current exchange is only valid within the function. If you want to achieve real exchange, you need to add pointer operations

2. Change the symbol

As shown in the figure, negate and add one to change the sign 

3. Take the absolute value

For positive numbers, the absolute value is itself

For negative numbers, the absolute value is negated plus one

4. Judging parity

 I personally feel that this method of judgment is more convenient

5. Finding the modulus

 15 % 4 = 3

6. Adding two numbers

 The process of adding two numbers is a bit troublesome. 


V. Summary

#include <stdio.h>

void swap(int a, int b);//两数交换数值
void change_sign(int a);//改变符号
void num_abs(int a);//求绝对值

int main(){
    // 运算时,都是根据补码进行运算的,正数补码与原码一样,而负数则是符号位不变,其余取反,末位加一
    // 取反运算:~
    // 15 原码:0000 1111   补码:0000 1111     ~15 --> 补码:1111 0000 --> 原码:1001 0000 --> -16
    //-15 原码:1000 1111   补码:1111 0001     ~-15 --> 补码:0000 1110 --> 原码:0000 1110 --> 14
    int a = 15, b = 16;
    int res = ~a;

    // ******************************************************************************
    // 与运算 & ,15 & 0 --> 0000 1111 & 0000 0000 = 0000 0000 即为 0
    // 或运算 | ,15 | 0 --> 0000 1111 | 0000 0000 = 0000 1111 即为自己本身
    // 异或运算 ^ 15 ^ -2 --> 0000 1111 ^ 1000 0010 == 0000 1111 ^ 1111 1111 = 1111 0000 --> 1000 1111 = -15
    // -15 ^ 2 --> 1000 1111 ^ 0000 0010 == 1111 0001 ^ 0000 0010 = 1111 0011 --> 1000 1101 即为 -13
    res = a ^ 2;
    printf("异或: a ^ 2 = %d \n\n", res);

    // ******************************************************************************
    // 左移 15 << k  二进制码全部向左移动 k 个,右边补 0  0000 1111 << 1 --> 0001 1110 即为 30
    // 左移 -15 << k    1111 0001 << 1 --> 1110 0010 --> 1001 1110 即为 -30
    // 右移 15 >> k  二进制码全部向右移动 k 个,左边补 0  0000 1111 >> 1 --> 0000 0111 即为 7
    // 右移 -15 >> k    1111 0001 >> 1 --> 1111 1000 --> 1000 1000 即为 -8 
    // 负数左边补 1,右边补 0
    res = a << 1;
    printf("左移: a << 1 = %d \n\n", res);

    // ******************************************************************************
    // 任何数                 << 1 === * 2 
    // 对于偶数来说            >> 1 === / 2
    // 16 << 1    0001 0000 --> 0010 1000 即为 32
    // 16 >> 1    0001 0000 --> 0000 1000 即为 8
    // 对于奇数,则在最后结果上加上0.5
    // 13 >> 1    0000 1101 --> 0000 0110 即为 6
    // 15 >> 1    0000 1111 --> 0000 0111 即为 7
    // 17 >> 1    0001 0001 --> 0000 1000 即为 8
    res = 15 >> 1;
    printf("右移: 15 >> 1 = %f \n\n", res + 0.5);

    // ******************************************************************************
    // 两数交换 1, 2
    // a = 1 ^ 2 --> 0000 0001 ^ 0000 0010 = 0000 0011 = 3
    // b = 2 ^ 3 --> 0000 0010 ^ 0000 0011 = 0000 0001 = 1
    // a = 3 ^ 1 --> 0000 0011 ^ 0000 0001 = 0000 0010 = 2
    // 交换完之后即为 2, 1
    swap(1, 2);

    // ******************************************************************************
    // 改变符号 -2
    // ~-2 + 1 --> 1000 0010 --> 1111 1110 --> 0000 0010 即为 2 
    // ~2 + 1  --> 0000 0010 --> 1111 1110 --> 1000 0010 即为 -2
    change_sign(-2);

    // ******************************************************************************
    // 求绝对值
    // 正数便返回正数
    num_abs(-2);

    // ******************************************************************************
    // 判断奇偶性  与 1 相与
    // 5 & 1 --> 0000 0101 & 0000 0001 = 0000 0001 = 1  奇数
    // 6 & 1 --> 0000 0110 & 0000 0001 = 0000 0000 = 0  偶数
    if (a & 1)
        printf("奇数\n\n");
    else
        printf("偶数\n\n");

    // ******************************************************************************
    // 求模  但是得是 2的k次方
    // 15 & (4 - 1) --> 0000 1111 & 0000 0011 = 0000 0011 = 3 即为 15 % 4 = 3
    printf("求模: a & (4 - 1) = %d \n\n", a & (4 - 1));

    // ******************************************************************************
    a = 13;
    b = 7;
    // 两数相加 13 + 7
    // 0000 1101 ^ 0000 0111 = 0000 1010 = 10
    // 0000 1101 & 0000 0111 = 0000 0101 << 1 --> 0000 1010 = 10
    // a = 10   b = 10
    // 0000 1010 ^ 0000 1010 = 0000 0000 = 0
    // 0000 1010 & 0000 1010 = 0000 1010 << 1 --> 0001 0100 = 20
    // a = 0    b = 20
    // 0000 0000 ^ 0001 0100 = 0001 0100 = 20
    // 0000 0000 & 0001 0100 = 0000 0000 << 1 --> 0000 0000 = 0
    // a = 20   b = 0
    // 循环结束,最后结果为 20
    while(b){
        int temp_a = a ^ b;
        int temp_b = (a & b) << 1;
        a = temp_a;
        b = temp_b;
    }
    printf("相加: 13 + 7 = %d\n\n", a);

    return 0;
}

void swap(int a, int b){
    printf("交换前: a = %d, b = %d\n", a, b);
    a ^= b;
    b ^= a;
    a ^= b;
    printf("交换后: a = %d, b = %d\n\n", a, b);
}

void change_sign(int a){
    printf("改变前的值: %d\n", a);
    printf("改变后的值: %d\n\n", ~a + 1);
}

void num_abs(int a){
    printf("求绝对值前的值: %d\n", a);
    // -2 >> 31 得到的是 -1
    // 负数右移,在左边补1,之后转成原码,即为 -1
    printf("求绝对值后的值: %d\n\n", a ^ (a >> 31) ? a : ~ a + 1);
}

The above is the operation of bit operation in C language that I have compiled. I hope it will be helpful to everyone.

Guess you like

Origin blog.csdn.net/m0_58182130/article/details/126599530