Python按位运算符的使用
任务要求
1.掌握按位运算符的二进制计算规则
2.实现数值处理、状态判断等应用场景
3.包含运算符优先级说明和复合用法
4.提供可扩展的代码模板
5.代码需兼容整数和负值处理
任务分析
Python按位运算符的特性:
1.二进制处理:直接操作整数二进制形式
2.效率优势:比常规运算快3-5倍
3.复合赋值:支持&=、|=等快捷写法
4.符号处理:负数采用补码表示法
5.应用边界:仅支持整型数据操作
任务实现
场景一:基础位运算演示
# 二进制转换辅助函数
def bin8(num): # 显示8位二进制
return format(num if num >= 0 else (1 << 8) + num, '08b')
a, b = 0b1010, 0b1100 # 10和12的二进制表示
print(f"按位与 {bin8(a)} & {bin8(b)} = {bin8(a & b)}") # 1000 (8)
print(f"按位或 {bin8(a)} | {bin8(b)} = {bin8(a | b)}") # 1110 (14)
print(f"按位异或 {bin8(a)} ^ {bin8(b)} = {bin8(a ^ b)}") # 0110 (6)
print(f"按位取反 ~{bin8(a)} = {bin8(~a)}") # 11110101 (-11)
print(f"左移两位 {bin8(a)} << 2 = {bin8(a << 2)}") # 101000 (40)
print(f"右移两位 {bin8(b)} >> 2 = {bin8(b >> 2)}") # 0011 (3)
运行结果:
按位与 00001010 & 00001100 = 00001000
按位或 00001010 | 00001100 = 00001110
按位异或 00001010 ^ 00001100 = 00000110
按位取反 ~00001010 = 11110101
左移两位 00001010 << 2 = 00101000
右移两位 00001100 >> 2 = 00000011
进程已结束,退出代码为 0
说明:
- bin8()函数处理负数补码显示
- num if num >= 0 else (1 << 8) + num用于处理二进制表示。对于非负数,直接使用num;对于负数,使用1 << 8(即256)加上该负数的值,以得到其8位补码表示。
- format(..., '08b')将整数格式化为8位二进制字符串。08b中的0表示用零填充,8表示字符串长度为8,b表示二进制格式。
- 按位运算符直接操作二进制每一位。
- a & b按位与操作,结果是1010与1100的按位与,即1000(二进制),对应十进制的8。
- a | b按位或操作,结果是1010与1100的按位或,即1110(二进制),对应十进制的14。
- a ^ b按位异或操作,结果是1010与1100的按位异或,即0110(二进制),对应十进制的6。
- ~a按位取反操作,对1010的每一位取反得到0101,但由于是在8位系统中解释,实际上得到了11110101(二进制),这对应于十进制的-11(注意:这里使用的是补码表示法)。
- a << 2将1010左移两位,得到101000(二进制),对应十进制的40。
- b >> 2将1100右移两位,得到0011(二进制),对应十进制的3。
案例1:奇偶判断与符号检测
def check_number(num):
is_even = num & 1 == 0 # 判断偶数
is_negative = num < 0
sign_bit = (num >> 31) & 1 # 获取符号位(32位系统)
return is_even, is_negative, sign_bit
print(check_number(-15)) # (False, True, 1)
运行结果:
(False, True, 1)
进程已结束,退出代码为 0
说明:
- check_number()函数,用于检查传入的整数num的三个特性:是否为偶数、是否为负数以及其在32位系统中的符号位。
- num & 1 == 0通过位运算来判断num是否为偶数。num & 1的含义是对num进行按位与运算,其中1的二进制表示为000...001(假设num为32位)。这个操作的结果实际上就是num的最低位,即其二进制表示的最右边一位。对于任何整数,若其最低位为0(即二进制为...0000),则该数为偶数;若最低位为1(即二进制为...0001),则为奇数。因此,num & 1 == 0返回True表示num是偶数,False则表示num是奇数。
- (num >> 31) & 1获取num在32位系统中的符号位。num >> 31表示将num的二进制位向右移动31位。对于正数,这样操作会导致最高位(符号位)变为0,其余位全为0;对于负数,在2的补码表示法中,最高位(符号位)为1,向右移动31位后,所有位都会变成1(因为负数的补码表示法中,最高位为1,其余位由该数的绝对值的反码加1得到,反码加1后的最高位仍然是1)。然后使用& 1获取最低位的值,这样就可以得到符号位的值。如果num为负数,则sign_bit为1;如果num为正数或零,则sign_bit为0。
案例2:变量值交换
x, y = 5, 8
x ^= y # 等价于 x = x ^ y
y ^= x # y = y ^ x → 原x值
x ^= y # x = x ^ y → 原y值
print(x, y) # 8 5
运行结果:
8 5
进程已结束,退出代码为 0
说明:这段代码的主要功能是使用按位异或运算符实现两个变量x和y的值交换。这种方法避免了使用额外的存储空间来保存中间值,是一种原地交换的方法。
案例3:简单加密算法
def encrypt(text, key):
return bytes([ord(c) ^ key for c in text])
secret = encrypt("Python", 0x55)
print(f"加密数据:{secret}") # b'\x15\x1e\x0c\x1d\x18\x17'
运行结果:
加密数据:b'\x05,!=:;'
进程已结束,退出代码为 0
说明:对给定的字符串使用简单的异或加密算法进行加密。异或加密是一种对称加密方法,即加密和解密使用相同的算法和密钥。字符串"Python"被密钥0x55加密,结果是一个字节对象。