基于算法竞赛的c++编程(24)位运算及其应用
本节主要是位运算及其相关应用
位运算基础概念
位运算是对整数在二进制位级别上的操作。C++提供了六种位运算符,包括按位与(&
)、按位或(|
)、按位异或(^
)、按位取反(~
)、左移(<<
)和右移(>>
)。这些操作通常用于优化性能或处理底层数据。
常用位运算符及示例
按位与(&
)
对应位均为1时结果为1,否则为0。常用于掩码操作或检测特定位。
示例:
int a = 5; // 0101
int b = 3; // 0011
int c = a & b; // 0001 (1)
按位或(|
)
对应位至少有一个1时结果为1。常用于设置特定位。
示例:
int a = 5; // 0101
int b = 3; // 0011
int c = a | b; // 0111 (7)
按位异或(^
)
对应位不同时结果为1。常用于交换变量或加密。
示例:
int a = 5; // 0101
int b = 3; // 0011
int c = a ^ b; // 0110 (6)
按位取反(~
)
所有位取反。常用于生成补码。
示例:
int a = 5; // 0101
int b = ~a; // 1010 (-6,取决于位数和符号表示)
左移(<<
)
将二进制位向左移动,低位补0。常用于快速乘法(左移n位相当于乘以2^n)。
示例:
int a = 5; // 0101
int b = a << 1; // 1010 (10)
右移(>>
)
将二进制位向右移动,高位补符号位(算术右移)或0(逻辑右移)。常用于快速除法(右移n位相当于除以2^n)。
示例:
int a = 5; // 0101
int b = a >> 1; // 0010 (2)
位运算的常见应用
快速判断奇偶性
通过检查最低位是否为1来判断奇数。
bool isOdd(int num) {return num & 1;
}
交换两个变量的值
利用异或运算无需临时变量。
void swap(int &a, int &b) {a ^= b;b ^= a;a ^= b;
}
计算绝对值
利用补码和位运算快速计算。
int abs(int num) {int mask = num >> (sizeof(int) * 8 - 1);return (num ^ mask) - mask;
}
检测2的幂
若n是2的幂,则n & (n - 1)为0。
bool isPowerOfTwo(int n) {return n > 0 && (n & (n - 1)) == 0;
}
位运算的优化技巧
快速乘除
左移和右移可替代部分乘除法操作。
int multiplyByTwo(int num) { return num << 1; }
int divideByTwo(int num) { return num >> 1; }
掩码操作
提取或设置特定位时使用掩码。
// 提取低4位
int low4Bits = num & 0xF;
// 设置第3位为1
num |= (1 << 2);
位计数(Population Count)
统计二进制中1的个数。
int countOnes(int n) {int count = 0;while (n) {n &= (n - 1);count++;}return count;
}
注意事项
- 位运算优先级通常低于算术运算,建议多用括号明确逻辑。
- 右移负数时结果依赖编译器实现(算术或逻辑右移)。
- 避免过度优化导致代码可读性下降。
通过合理使用位运算,可以显著提升某些场景下的性能表现,尤其在嵌入式开发或算法竞赛中尤为常见。