📜  使用位操作进行空间优化(1)

📅  最后修改于: 2023-12-03 15:22:22.196000             🧑  作者: Mango

使用位操作进行空间优化

在程序开发中,空间优化是非常重要的,尤其是在一些资源有限的嵌入式系统、移动设备等场景。位操作是非常有效的空间优化手段之一,通过对变量使用位运算来代替常规运算,可以显著地降低内存占用,提升程序效率。

1. 位运算

位运算是对二进制数字进行的操作,包括位与(&)、位或(|)、位异或(^)、位取反(~)和移位(<<、>>)。下面简单介绍一下这几种运算的含义和作用。

1.1 位与(&)

位与运算的两个操作数都是二进制数,其规则是将两个操作数对应的二进制位进行按位“与”操作,如果两个对应的二进制位都为1,则该位的结果为1,否则该位的结果为0。

如:3 & 5 = 1

3 的二进制数为 0011
5 的二进制数为 0101
     &
结果为 0001
1.2 位或(|)

位或运算的两个操作数也都是二进制数,其规则是将两个操作数对应的二进制位进行按位“或”操作,如果其中一个对应的二进制位为1,则该位的结果为1,否则该位的结果为0。

如:3 | 5 = 7

3 的二进制数为 0011
5 的二进制数为 0101
     |
结果为 0111
1.3 位异或(^)

位异或运算的两个操作数也都是二进制数,其规则是将两个操作数对应的二进制位进行按位“异或”操作,如果两个对应的二进制位不同,则该位的结果为1,否则该位的结果为0。

如:3 ^ 5 = 6

3 的二进制数为 0011
5 的二进制数为 0101
     ^
结果为 0110
1.4 位取反(~)

位取反运算是对一个二进制数的所有位进行按位取反操作,即0变成1,1变成0。

如:~3 = -4

3 的二进制数为 0011
     ~
结果为 1100,也就是 -4
1.5 移位(<<、>>)

移位运算是将一个二进制数的所有位进行左移或右移操作,相当于对该数进行乘以2或除以2的操作。

左移操作(<<)即将一个二进制数的所有位往左移动n位,低位补0,相当于该数乘以2的n次方。

如:3 << 2 = 12

3 的二进制数为 0011,左移2位变成 1100
结果为 12

右移操作(>>)即将一个二进制数的所有位往右移动n位,高位补0或补1,相当于该数除以2的n次方。

如:-4 >> 2 = -1

-4 的二进制数为 1100,右移2位变成 1111
结果为 -1
2. 利用位运算进行空间优化

在编写程序时,有些类型的数据可能会占用比较大的内存空间,比如int、float等,而在某些情况下,我们只需要使用其中一部分数据,比如只需要使用int类型数据的前8位。这时我们可以利用位运算进行空间优化。

以下是一些常见的位运算技巧:

2.1 位运算交换值

用位运算交换值可以减少使用额外的变量的内存占用。

void swap(int* a, int* b) 
{
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}
2.2 判断奇偶性

用位运算判断奇偶性可以减少使用条件语句的内存占用。

int is_odd(int n) 
{
    return n & 1;
}
2.3 取绝对值

用位运算取绝对值可以减少使用条件语句的内存占用。

int abs(int n) 
{
    int const mask = n >> (sizeof(int) * CHAR_BIT - 1);
    return (n + mask) ^ mask;
}
2.4 判断数字是否是2的幂

用位运算判断数字是否是2的幂可以减少使用条件语句的内存占用。

int is_power_of_two(int n) 
{
    return n && !(n & (n - 1));
}
2.5 将数字转为二进制数

用位运算将数字转为二进制数可以减少使用字符串的内存占用。

void print_binary(int n) 
{
    for (int i = 31; i >= 0; --i) {
        printf("%d", (n >> i) & 1);
    }
}
3. 总结

位操作是一种非常有效的空间优化手段,通过对变量使用位运算来代替常规运算,可以显著地降低内存占用,提升程序效率。在编写程序时,我们可以根据实际需求采用不同的位运算技巧进行优化,从而提高程序的性能和效率。