常用的位运算技巧及其意义
位运算在计算机科学中非常常见,因其高效性和灵活性而被广泛使用。以下是一些常用的位运算技巧及其意义:
1. 按位与(AND)
- 操作符:
& - 含义:对两个操作数的每一位执行与操作。如果两个相应的位都为1,则结果为1;否则为0。
- 应用:
- 提取状态位:在一个位掩码中提取特定的状态位。
- 清除位:通过与一个掩码进行与操作来清除某些位。例如,
x & ~mask可以清除x中mask指定的位置为1的位。 - 检查标志:检查一个位掩码中的某些标志是否被设置。
2. 按位或(OR)
- 操作符:
| - 含义:对两个操作数的每一位执行或操作。如果两个相应的位中至少有一个为1,则结果为1;否则为0。
- 应用:
- 设置标志:通过与一个掩码进行或操作来设置某些标志。例如,
x | mask可以设置x中mask指定的位置为1的位。 - 合并状态:合并多个位掩码的状态。
- 设置标志:通过与一个掩码进行或操作来设置某些标志。例如,
3. 按位异或(XOR)
- 操作符:
^ - 含义:对两个操作数的每一位执行异或操作。如果两个相应的位不同,则结果为1;否则为0。
- 应用:
- 切换标志:通过异或操作来切换某些标志。例如,
x ^ mask可以切换x中mask指定的位置为1的位。 - 加法不进位:XOR 操作可以用于无符号整数的加法而不考虑进位。
- 加密和校验:XOR 常用于简单的加密和校验算法,因为它的可逆性。
- 切换标志:通过异或操作来切换某些标志。例如,
4. 按位取反(NOT)
- 操作符:
~ - 含义:对操作数的每一位执行取反操作。0 变为 1,1 变为 0。
- 应用:
- 清除位:通过按位与和按位取反操作来清除某些位。例如,
x & ~mask。 - 设置位:通过按位或和按位取反操作来设置某些位。例如,
x | ~mask(虽然不常见)。
- 清除位:通过按位与和按位取反操作来清除某些位。例如,
5. 左移(Left Shift)
- 操作符:
<< - 含义:将操作数的二进制位向左移动指定的位数,右侧用0填充。
- 应用:
- 乘以2的幂:左移
n位相当于将数乘以2^n。 - 算术运算:用于快速计算乘法和除法,特别是在需要处理二进制位的情况下。
- 乘以2的幂:左移
6. 右移(Right Shift)
- 操作符:
>> - 含义:将操作数的二进制位向右移动指定的位数。右侧用0填充,左侧取决于操作数的符号(算术右移)。
- 应用:
- 除以2的幂:右移
n位相当于将数除以2^n(对于无符号数)。 - 算术运算:用于快速计算乘法和除法,特别是在需要处理二进制位的情况下。
- 除以2的幂:右移
7. 提取最低有效位(LSB)
- 操作:
x & -x - 含义:提取
x中最低的有效位(即最右边的第一个1位)。 - 应用:
- 状态管理:在位掩码中提取当前激活的最低状态。
- 优化性能:快速找到位掩码中最低的1位。
8. 清除最低有效位(LSB)
- 操作:
x & (x - 1) - 含义:清除
x中最低的有效位。 - 应用:
- 状态管理:在位掩码中清除当前激活的最低状态。
- 优化性能:快速清除位掩码中最低的1位。
9. 检查是否只有一个位为1
- 操作:
(x & (x - 1)) == 0 - 含义:检查
x是否只有一个位为1。 - 应用:
- 状态管理:确保一个位掩码中只有一个状态被激活。
- 优化性能:快速判断一个数是否是2的幂(因为2的幂在二进制中只有一个1位)。
10. 取反最低有效位(LSB)
- 操作:
x ^ (x & -x) - 含义:对
x中最低的有效位进行取反。 - 应用:
- 状态管理:在位掩码中切换当前激活的最低状态。
11. 计算位掩码中的1位数量
- 操作:
x & (x - 1)可以用于循环中计算1位的数量。 - 含义:通过循环不断清除最低的有效位,直到
x变为0,统计循环次数即为1位的数量。 - 应用:
- 统计状态:计算位掩码中激活的状态数量。
12. 使用位掩码进行条件判断
- 操作:
if x & mask: - 含义:检查
x中是否有mask中指定的任何位被设置为1。 - 应用:
- 条件判断:在需要检查多个条件时,使用位掩码可以提高效率。
13. 使用位掩码进行多重条件设置
- 操作:
x |= mask1 | mask2 | ... | maskN - 含义:将多个掩码合并到
x中,设置多个位。 - 应用:
- 设置多个状态:在需要同时设置多个状态时,使用位掩码可以简化操作。
14. 使用位掩码进行多重条件清除
- 操作:
x &= ~(mask1 | mask2 | ... | maskN) - 含义:将多个掩码合并后取反,然后与
x进行与操作,清除多个位。 - 应用:
- 清除多个状态:在需要同时清除多个状态时,使用位掩码可以简化操作。
15. 使用位掩码进行多重条件切换
- 操作:
x ^= mask1 ^ mask2 ^ ... ^ maskN - 含义:将多个掩码合并后进行异或操作,切换多个位。
- 应用:
- 切换多个状态:在需要同时切换多个状态时,使用位掩码可以简化操作。
示例代码
以下是一些示例代码,展示了上述位运算技巧的应用:
class BitOperations:
def __init__(self, anim_status=0):
self.anim_status = anim_status
def set_status(self, status):
self.anim_status |= status
print("Set anim_status:", self.anim_status)
def clear_status(self, status):
self.anim_status &= ~status
print("Clear anim_status:", self.anim_status)
def toggle_status(self, status):
self.anim_status ^= status
print("Toggle anim_status:", self.anim_status)
def get_active_status(self):
active_status = self.anim_status & -self.anim_status
print("Active status:", active_status)
return active_status
def clear_active_status(self):
self.anim_status &= (self.anim_status - 1)
print("Clear active status:", self.anim_status)
def count_ones(self):
count = 0
temp = self.anim_status
while temp:
temp &= (temp - 1)
count += 1
print("Count of ones:", count)
return count
def is_power_of_two(self):
is_power = (self.anim_status & (self.anim_status - 1)) == 0 and self.anim_status != 0
print("Is power of two:", is_power)
return is_power
# 示例使用
if __name__ == "__main__":
test = BitOperations()
EAnimStatus = {
"RUN": 1 << 0, # 00000001
"JUMP": 1 << 1, # 00000010
"ATTACK": 1 << 2, # 00000100
"DEFEND": 1 << 3 # 00001000
}
test.set_status(EAnimStatus["RUN"])
test.set_status(EAnimStatus["JUMP"])
test.get_active_status()
test.clear_active_status()
test.count_ones()
test.is_power_of_two()
总结
位运算技巧在处理状态、标志、权限、加密、优化性能等方面非常有用。通过这些技巧,可以高效地操作和检查二进制位,从而提高程序的性能和可读性。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Beyond Lightcone!

