📅  最后修改于: 2023-12-03 15:22:22.196000             🧑  作者: Mango
在程序开发中,空间优化是非常重要的,尤其是在一些资源有限的嵌入式系统、移动设备等场景。位操作是非常有效的空间优化手段之一,通过对变量使用位运算来代替常规运算,可以显著地降低内存占用,提升程序效率。
位运算是对二进制数字进行的操作,包括位与(&)、位或(|)、位异或(^)、位取反(~)和移位(<<、>>)。下面简单介绍一下这几种运算的含义和作用。
位与运算的两个操作数都是二进制数,其规则是将两个操作数对应的二进制位进行按位“与”操作,如果两个对应的二进制位都为1,则该位的结果为1,否则该位的结果为0。
如:3 & 5 = 1
3 的二进制数为 0011
5 的二进制数为 0101
&
结果为 0001
位或运算的两个操作数也都是二进制数,其规则是将两个操作数对应的二进制位进行按位“或”操作,如果其中一个对应的二进制位为1,则该位的结果为1,否则该位的结果为0。
如:3 | 5 = 7
3 的二进制数为 0011
5 的二进制数为 0101
|
结果为 0111
位异或运算的两个操作数也都是二进制数,其规则是将两个操作数对应的二进制位进行按位“异或”操作,如果两个对应的二进制位不同,则该位的结果为1,否则该位的结果为0。
如:3 ^ 5 = 6
3 的二进制数为 0011
5 的二进制数为 0101
^
结果为 0110
位取反运算是对一个二进制数的所有位进行按位取反操作,即0变成1,1变成0。
如:~3 = -4
3 的二进制数为 0011
~
结果为 1100,也就是 -4
移位运算是将一个二进制数的所有位进行左移或右移操作,相当于对该数进行乘以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
在编写程序时,有些类型的数据可能会占用比较大的内存空间,比如int、float等,而在某些情况下,我们只需要使用其中一部分数据,比如只需要使用int类型数据的前8位。这时我们可以利用位运算进行空间优化。
以下是一些常见的位运算技巧:
用位运算交换值可以减少使用额外的变量的内存占用。
void swap(int* a, int* b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
用位运算判断奇偶性可以减少使用条件语句的内存占用。
int is_odd(int n)
{
return n & 1;
}
用位运算取绝对值可以减少使用条件语句的内存占用。
int abs(int n)
{
int const mask = n >> (sizeof(int) * CHAR_BIT - 1);
return (n + mask) ^ mask;
}
用位运算判断数字是否是2的幂可以减少使用条件语句的内存占用。
int is_power_of_two(int n)
{
return n && !(n & (n - 1));
}
用位运算将数字转为二进制数可以减少使用字符串的内存占用。
void print_binary(int n)
{
for (int i = 31; i >= 0; --i) {
printf("%d", (n >> i) & 1);
}
}
位操作是一种非常有效的空间优化手段,通过对变量使用位运算来代替常规运算,可以显著地降低内存占用,提升程序效率。在编写程序时,我们可以根据实际需求采用不同的位运算技巧进行优化,从而提高程序的性能和效率。