Python 中数据的位运算和状态编码(掩码)详解

发布于:2025-07-31 ⋅ 阅读:(20) ⋅ 点赞:(0)

Python 中数据的位运算

在 Python 中,位运算(bitwise operation) 是对整数在二进制层面进行操作的常见方式,通常用于性能优化、状态编码、底层硬件交互等。


一、位逻辑运算简介

位逻辑运算符是对 整数的二进制表示的每一位 进行操作。

运算符 名称 作用 示例
& 位与 同为 1 ⇒ 结果为 1 5 & 3
` ` 位或 任一为 1 ⇒ 结果为 1 `5 3`
^ 位异或 不同为 1 ⇒ 相同为 0 5 ^ 3
~ 取反 所有位取反(含符号位) ~5

1. 位与(AND)&

a = 0b0101  # 5
b = 0b0011  # 3
print(bin(a & b))  # 0b0001 => 1

2. 位或(OR)|

a = 0b0101  # 5
b = 0b0011  # 3
print(bin(a | b))  # 0b0111 => 7

3. 位异或(XOR)^

a = 0b0101  # 5
b = 0b0011  # 3
print(bin(a ^ b))  # 0b0110 => 6

4. 位取反(NOT)~

注意:Python 中取反是按补码进行(即 ~x = -x - 1

a = 5  # 二进制:0000 0101
print(~a)     # -6
print(bin(~a))  # -0b110

二、移位运算(shift)

运算符 名称 说明
<< 左移 相当于乘以 2 的 n 次方
>> 右移 相当于除以 2 的 n 次方(向下取整)

1. 左移 <<

a = 3       # 0b0011
print(a << 2)    # 12
print(bin(a << 2))  # 0b1100

左移 n 位 等价于 a * 2**n


2. 右移 >>

a = 16      # 0b10000
print(a >> 2)    # 4
print(bin(a >> 2))  # 0b100

右移 n 位 等价于 a // 2**n


三、常见应用实例

1. 判断奇偶数(用位与)

def is_odd(n):
    return n & 1 == 1

print(is_odd(5))  # True
print(is_odd(8))  # False

2. 交换两个数(不使用临时变量)

a, b = 5, 3
a = a ^ b
b = a ^ b
a = a ^ b
print(a, b)  # 3 5

3. 清零最低位的 1(如 0b10100 → 0b10000)

x = 20  # 0b10100
print(bin(x & (x - 1)))  # 0b10000

4. 获取最低位的 1

x = 20  # 0b10100
print(bin(x & -x))  # 0b100

5. 统计二进制中 1 的个数(Brian Kernighan 算法)

def count_ones(n):
    count = 0
    while n:
        n &= (n - 1)
        count += 1
    return count

print(count_ones(15))  # 4 (0b1111)

四、完整汇总表(逻辑运算 vs 二进制)

假设 a = 5 (0b0101), b = 3 (0b0011)

表达式 运算 结果(二进制) 结果(十进制)
a & b 位与 0b0001 1
`a b` 位或 0b0111 7
a ^ b 位异或 0b0110 6
~a 位取反 -0b0110 -6
a << 1 左移 1 位 0b1010 10
a >> 1 右移 1 位 0b0010 2

五、小结

运算符 名称 关键理解点
& 两位都为 1,结果才为 1
` ` 任意一位为 1,结果为 1
^ 异或 两位不同,结果为 1
~ 取反 与符号位有关,结果为 -x - 1
<< 左移 乘以 2 的 n 次方(整数部分)
>> 右移 除以 2 的 n 次方(向下取整)

Python 中状态编码(掩码)

Python 中的状态编码(掩码)权限控制(二进制位模拟),这些技术常用于:

  • 操作系统中的权限(读写执行)
  • 嵌入式系统中的状态位
  • 游戏中角色状态(如“中毒”、“冰冻”、“隐身”等)
  • 8 位或 16 位“寄存器模拟器”

一、状态编码与掩码(bitmask)

掩码(mask) 是一种位标记机制,用二进制的每一位表示某种“状态”或“权限”。

1. 权限示例(类 Unix 权限)

权限 二进制位 十进制
读(R) 0b100 4
写(W) 0b010 2
执行(X) 0b001 1

一个用户有读+执行权限:0b101 = 5


2. 掩码操作函数示例

# 定义权限位
READ  = 0b100
WRITE = 0b010
EXEC  = 0b001

# 设置权限(或运算)
perm = 0
perm |= READ     # 添加读权限
perm |= EXEC     # 添加执行权限

print(f"当前权限: {bin(perm)}")  # 0b101

# 检查权限(与运算)
def has_permission(p, flag):
    return (p & flag) != 0

print("有写权限?", has_permission(perm, WRITE))  # False
print("有读权限?", has_permission(perm, READ))   # True

# 移除权限(与取反)
perm &= ~READ
print(f"移除读权限后: {bin(perm)}")  # 0b001

二、使用枚举构建权限系统(更清晰)

from enum import IntFlag

class Permission(IntFlag):
    READ = 4
    WRITE = 2
    EXEC = 1

# 设置权限
perm = Permission.READ | Permission.EXEC
print(f"当前权限: {perm}")

# 检查
print("有写权限?", Permission.WRITE in perm)
print("有读权限?", Permission.READ in perm)

三、8 位寄存器模拟(位标记系统)

示例:控制器状态位

位索引 状态名 说明
0 POWER_ON 电源开启
1 ERROR 错误状态
2 BUSY 正在处理
3 SLEEP 休眠状态
4-7 保留 -

实现寄存器模拟类

class Register8:
    POWER_ON = 1 << 0  # 0b00000001
    ERROR    = 1 << 1  # 0b00000010
    BUSY     = 1 << 2  # 0b00000100
    SLEEP    = 1 << 3  # 0b00001000

    def __init__(self):
        self.reg = 0  # 所有状态位初始为 0

    def set(self, flag):
        self.reg |= flag

    def clear(self, flag):
        self.reg &= ~flag

    def toggle(self, flag):
        self.reg ^= flag

    def check(self, flag):
        return (self.reg & flag) != 0

    def show(self):
        return f"{self.reg:08b}"  # 显示为 8 位二进制

# 示例使用
reg = Register8()
reg.set(Register8.POWER_ON)
reg.set(Register8.BUSY)

print("状态位:", reg.show())  # 00000101

print("BUSY 状态?", reg.check(Register8.BUSY))  # True

reg.clear(Register8.BUSY)
print("清除 BUSY 后:", reg.show())  # 00000001

四、游戏角色状态示例(组合状态)

class Status:
    POISON = 1 << 0  # 中毒
    FROZEN = 1 << 1  # 冻结
    INVIS  = 1 << 2  # 隐身

hero = 0
hero |= Status.POISON | Status.INVIS
print("角色状态:", bin(hero))  # 0b101

# 解除隐身
hero &= ~Status.INVIS
print("解除隐身后:", bin(hero))  # 0b001

五、小结:常见操作模式

目标 操作符与策略
添加状态 `a = flag`
移除状态 a &= ~flag
翻转状态 a ^= flag
检查状态 (a & flag) != 0


网站公告

今日签到

点亮在社区的每一天
去签到