Python基础指南之位运算符与二进制运算入门详解
一、开篇:为什么要学位运算
很多Python初学者看到&、|、^、<<、>>这些运算符时,第一反应是:“我用Python写业务代码,还需要学位运算?”
答案是:需要的。虽然位运算不像if-else那样每天都要写,但它在以下场景中无处不在:
- 权限系统设计(用位表示权限,一个整数代替一堆布尔值)
- 性能优化(位运算比算术运算快得多)
- 颜色处理(RGB值的提取与合并)
- 网络编程(IP地址、子网掩码计算)
- 数据压缩与加密(底层算法的基础)
- 状态标记(用一个整数表示多种状态的组合)
更重要的是,理解位运算能让你真正理解计算机是如何看待数据的——毕竟,在底层,一切都是0和1。
今天这篇文章,我们就从二进制基础开始,逐步掌握Python中所有位运算符的使用方法和实战场景。
二、二进制基础速成
2.1 为什么要用二进制
计算机用二进制(而非十进制)存储和处理数据,是因为二进制只需要两种状态(开/关、高电压/低电压),这在物理上最容易实现且最可靠。
2.2 二进制与十进制的转换
# Python中表示二进制数:用 0b 或 0B 前缀
a = 0b1010 # 二进制1010 = 十进制10
b = 0b1111 # 二进制1111 = 十进制15
print(a) # 10 —— Python内部以十进制显示
print(b) # 15
# 十进制转二进制字符串
print(bin(10)) # 0b1010
print(bin(255)) # 0b11111111
print(bin(0)) # 0b0
# 格式化为不带前缀的二进制
print(format(10, 'b')) # 1010
print(format(255, '08b')) # 11111111 —— 补齐8位
# 手动转换:十进制 → 二进制(理解原理)
def decimal_to_binary(n):
"""十进制转二进制(正整数)"""
if n == 0:
return '0'
bits = []
while n > 0:
bits.append(str(n % 2))
n //= 2
return ''.join(reversed(bits))
print(decimal_to_binary(10)) # 1010
print(decimal_to_binary(255)) # 11111111
# 二进制 → 十进制(理解原理)
def binary_to_decimal(binary_str):
"""二进制字符串转十进制"""
result = 0
for bit in binary_str:
result = result * 2 + int(bit)
return result
print(binary_to_decimal('1010')) # 10
print(binary_to_decimal('11111111')) # 255
2.3 二进制的基本概念
# 比特(bit):二进制的一位,只能是0或1 # 字节(byte):8个比特 # bit 的编号(从右往左,从0开始) # 二进制:1 0 1 0 # 位号: 3 2 1 0 # 权重: 8 4 2 1 # 每一位的权重是 2 的 n 次方 # 位0: 2^0 = 1 # 位1: 2^1 = 2 # 位2: 2^2 = 4 # 位3: 2^3 = 8 # 1010 = 8 + 0 + 2 + 0 = 10 # 查看一个整数占用的比特数 print((10).bit_length()) # 4 —— 1010需要4位 print((255).bit_length()) # 8 —— 11111111需要8位 print((256).bit_length()) # 9 —— 100000000需要9位 print((0).bit_length()) # 0
2.4 其他进制表示
# Python中的进制表示
binary = 0b1010 # 二进制 (binary)
octal = 0o755 # 八进制 (octal)
decimal = 255 # 十进制 (decimal)
hexadecimal = 0xFF # 十六进制 (hexadecimal)
print(binary, octal, decimal, hexadecimal) # 10 493 255 255
# 转换函数
print(bin(255)) # '0b11111111' 十进制→二进制字符串
print(oct(255)) # '0o377' 十进制→八进制字符串
print(hex(255)) # '0xff' 十进制→十六进制字符串
print(int('0b1111', 2)) # 15 二进制字符串→十进制
print(int('0o17', 8)) # 15 八进制字符串→十进制
print(int('0xf', 16)) # 15 十六进制字符串→十进制
# 格式化输出不同进制
n = 42
print(f"十进制: {n}")
print(f"二进制: {n:b}")
print(f"八进制: {n:o}")
print(f"十六进制: {n:x}")
print(f"二进制(8位): {n:08b}")
print(f"十六进制(大写): {n:X}")
三、Python的位运算符全解
3.1 按位与 & —— 两位都为1才得1
# & 的运算规则(逐位):
# 1 & 1 = 1
# 1 & 0 = 0
# 0 & 1 = 0
# 0 & 0 = 0
a = 0b1100 # 12
b = 0b1010 # 10
# = 0b1000 # 8
print(f"{a:04b}") # 1100
print(f"{b:04b}") # 1010
print(f"{a & b:04b}") # 1000
print(a & b) # 8
# & 的实际应用:判断某一位是否为1
# 检查第2位(从0开始)是否为1
def is_bit_set(n, position):
"""判断n的第position位是否为1"""
return (n & (1 << position)) != 0
print(is_bit_set(0b1100, 2)) # True —— 1100的第2位是1
print(is_bit_set(0b1100, 0)) # False —— 1100的第0位是0
print(is_bit_set(0b1100, 3)) # True —— 1100的第3位是1
# & 的常用技巧:取低N位(掩码操作)
def low_n_bits(n, num_bits):
"""获取n的低num_bits位"""
mask = (1 << num_bits) - 1
return n & mask
print(bin(low_n_bits(0b11010110, 4))) # 0b110 —— 取低4位
3.2 按位或 | —— 任一位为1就得1
# | 的运算规则(逐位):
# 1 | 1 = 1
# 1 | 0 = 1
# 0 | 1 = 1
# 0 | 0 = 0
a = 0b1100 # 12
b = 0b1010 # 10
# | = 0b1110 # 14
print(f"{a:04b}") # 1100
print(f"{b:04b}") # 1010
print(f"{a | b:04b}") # 1110
print(a | b) # 14
# | 的实际应用:设置某一位为1
def set_bit(n, position):
"""将n的第position位设为1"""
return n | (1 << position)
print(bin(set_bit(0b1000, 1))) # 0b1010 —— 设置了第1位
print(bin(set_bit(0b1000, 2))) # 0b1100 —— 设置了第2位
# | 的常用技巧:合并标志位(权限系统的基础)
READ = 0b001 # 1 —— 读权限
WRITE = 0b010 # 2 —— 写权限
EXECUTE = 0b100 # 4 —— 执行权限
# 赋予读写权限
permission = READ | WRITE
print(f"权限: {permission:03b}") # 011
print(f"权限值: {permission}") # 3
# 追加执行权限
permission |= EXECUTE
print(f"权限: {permission:03b}") # 111
print(f"权限值: {permission}") # 7
3.3 按位异或 ^ —— 两位不同得1,相同得0
# ^ 的运算规则(逐位):
# 1 ^ 1 = 0
# 1 ^ 0 = 1
# 0 ^ 1 = 1
# 0 ^ 0 = 0
a = 0b1100 # 12
b = 0b1010 # 10
# ^ = 0b0110 # 6
print(f"{a:04b}") # 1100
print(f"{b:04b}") # 1010
print(f"{a ^ b:04b}") # 0110
print(a ^ b) # 6
# ^ 的实际应用1:切换某一位(toggle)
def toggle_bit(n, position):
"""翻转n的第position位(1变0,0变1)"""
return n ^ (1 << position)
x = 0b1010 # 10
print(bin(toggle_bit(x, 0))) # 0b1011 —— 第0位从0变1
print(bin(toggle_bit(x, 1))) # 0b1000 —— 第1位从1变0
print(bin(toggle_bit(x, 3))) # 0b10 —— 第3位从1变0
# ^ 的实际应用2:不使用临时变量交换两个整数
a = 10
b = 20
print(f"交换前: a={a}, b={b}")
a ^= b # a = a ^ b
b ^= a # b = b ^ a = b ^ (a ^ b) = a
a ^= b # a = a ^ b = (a ^ b) ^ a = b
print(f"交换后: a={a}, b={b}")
# 但Python中直接用 a, b = b, a 更优雅!
# ^ 的实际应用3:找出数组中唯一出现奇数次的数
def find_odd_occurrence(arr):
"""在一个数组中,除了一个数出现奇数次,其他都出现偶数次,找出这个数"""
result = 0
for num in arr:
result ^= num # 相同数异或得0,最终只剩出现奇数次的数
return result
arr = [1, 2, 3, 2, 1, 3, 4, 5, 4]
print(find_odd_occurrence(arr)) # 5
# ^ 的实际应用4:简单的加密/解密
def xor_cipher(text, key):
"""简单的异或加密(对称加密)"""
return ''.join(chr(ord(c) ^ key) for c in text)
original = "Hello World"
encrypted = xor_cipher(original, 42)
decrypted = xor_cipher(encrypted, 42) # 再次异或同一个key即解密
print(f"原文: {original}")
print(f"加密: {encrypted!r}")
print(f"解密: {decrypted}")
3.4 按位取反 ~ —— 0变1,1变0
# ~ 的运算规则:对每一位取反
# 但在Python中,整数是无限精度的(用补码表示)
# ~n = -(n + 1)
print(~0) # -1
print(~1) # -2
print(~10) # -11
print(~-10) # 9
# 理解:Python使用补码表示负数
# 补码 = 反码 + 1
# ~n 对于正数:-(n + 1)
# ~n 对于负数:-(n + 1)(同样适用)
# 验证
for n in [0, 1, 5, -1, -5, 10, -10]:
print(f"~{n:>4} = {~n:>4} (预期: {-(n+1):>4})")
# 实际应用:快速计算 -(n+1)
# 虽然不常用,但了解其含义对于理解位运算很重要
# 如果你需要真正按位取反(固定位宽),需要配合掩码
def bitwise_not_fixed(n, num_bits=8):
"""固定位宽的按位取反"""
mask = (1 << num_bits) - 1
return (~n) & mask
print(bin(bitwise_not_fixed(0b1100, 8))) # 0b11110011
3.5 左移 << —— 所有位向左移动,右侧补0
# << 左移:所有位向左移动n位,右边补0
# 左移n位 = 乘以 2^n
x = 0b0001 # 1
print(bin(x << 1)) # 0b10 = 2 (= 1 * 2)
print(bin(x << 2)) # 0b100 = 4 (= 1 * 4)
print(bin(x << 3)) # 0b1000 = 8 (= 1 * 8)
# 左移的算术含义:x << n = x * (2 ** n)
for n in range(6):
print(f"1 << {n} = {1 << n:>3} (2^{n} = {2**n})")
# 实用技巧:快速计算2的幂
print(1 << 0) # 1 = 2^0
print(1 << 1) # 2 = 2^1
print(1 << 10) # 1024 = 2^10
print(1 << 20) # 1048576 = 2^20
# 创建特定位的掩码
BIT_0 = 1 << 0 # 0b0001 = 1
BIT_1 = 1 << 1 # 0b0010 = 2
BIT_2 = 1 << 2 # 0b0100 = 4
BIT_3 = 1 << 3 # 0b1000 = 8
# 大数左移
print(1 << 100) # Python支持任意大的整数!
3.6 右移 >> —— 所有位向右移动,左侧补符号位
# >> 右移:所有位向右移动n位,左侧补符号位(算术右移)
# 右移n位 = 除以 2^n(向下取整)
x = 0b1000 # 8
print(bin(x >> 1)) # 0b100 = 4 (= 8 // 2)
print(bin(x >> 2)) # 0b10 = 2 (= 8 // 4)
print(bin(x >> 3)) # 0b1 = 1 (= 8 // 8)
print(bin(x >> 4)) # 0b0 = 0
# 右移的算术含义:x >> n = x // (2 ** n)
for n in range(5):
print(f"16 >> {n} = {16 >> n} (16 // {2**n} = {16 // 2**n})")
# 负数右移 —— Python使用算术右移(补符号位)
print(-16 >> 1) # -8
print(-16 >> 2) # -4
print(-15 >> 1) # -8 —— 注意:-15 // 2 = -8(向下取整)
# 快速除以2的幂
print(100 >> 2) # 25 (= 100 // 4)
print(100 >> 3) # 12 (= 100 // 8)
print(100 >> 4) # 6 (= 100 // 16)
# 提取特定位:右移 + 掩码
def get_bits(n, start, count):
"""从n中提取从start位开始的count位"""
return (n >> start) & ((1 << count) - 1)
# 从0b10110110中提取第3-5位(从0开始)
n = 0b10110110 # 182
# 位: 7 6 5 4 3 2 1 0
# 1 0 1 1 0 1 1 0
# 提取第3-5位(即第3,4,5位:110)
print(bin(get_bits(n, 3, 3))) # 0b110
四、位运算实战:权限系统设计
这是位运算最经典的应用场景之一:
class Permission:
"""基于位运算的权限系统"""
# 定义权限常量(每个权限占一个位)
READ = 1 << 0 # 0b000001 = 1
WRITE = 1 << 1 # 0b000010 = 2
EXECUTE = 1 << 2 # 0b000100 = 4
DELETE = 1 << 3 # 0b001000 = 8
ADMIN = 1 << 4 # 0b010000 = 16
@staticmethod
def has_permission(user_perm, perm):
"""检查是否拥有某项权限"""
return (user_perm & perm) != 0
@staticmethod
def grant(user_perm, perm):
"""授予权限"""
return user_perm | perm
@staticmethod
def revoke(user_perm, perm):
"""撤销权限"""
return user_perm & (~perm)
@staticmethod
def toggle(user_perm, perm):
"""切换权限"""
return user_perm ^ perm
@staticmethod
def permission_names(perm_value):
"""将权限值转换为权限名列表"""
names = []
for name in ['READ', 'WRITE', 'EXECUTE', 'DELETE', 'ADMIN']:
if perm_value & getattr(Permission, name):
names.append(name)
return names
# 使用演示
user1_perm = Permission.READ | Permission.WRITE # 读写权限 = 3
print(f"初始权限: {Permission.permission_names(user1_perm)}")
# 检查权限
print(f"有读权限: {Permission.has_permission(user1_perm, Permission.READ)}")
print(f"有删除权限: {Permission.has_permission(user1_perm, Permission.DELETE)}")
# 授予执行权限
user1_perm = Permission.grant(user1_perm, Permission.EXECUTE)
print(f"授予EXECUTE后: {Permission.permission_names(user1_perm)}")
# 撤销写权限
user1_perm = Permission.revoke(user1_perm, Permission.WRITE)
print(f"撤销WRITE后: {Permission.permission_names(user1_perm)}")
# 切换管理员权限
user1_perm = Permission.toggle(user1_perm, Permission.ADMIN)
print(f"切换ADMIN后: {Permission.permission_names(user1_perm)}")
五、位运算实战:颜色处理
def rgb_to_hex(r, g, b):
"""RGB颜色值转换为十六进制颜色码"""
# 方式1:位运算
return f"#{(r << 16) | (g << 8) | b:06X}"
# 等价操作:
# 红色分量左移16位: r << 16
# 绿色分量左移8位: g << 8
# 蓝色分量不移动: b
# 三者按位或合并
print(rgb_to_hex(255, 128, 0)) # #FF8000
print(rgb_to_hex(0, 255, 0)) # #00FF00
print(rgb_to_hex(52, 152, 219)) # #3498DB
print(rgb_to_hex(255, 255, 255)) # #FFFFFF
def hex_to_rgb(hex_color):
"""十六进制颜色码转换为RGB值"""
hex_color = hex_color.lstrip('#')
value = int(hex_color, 16)
# 提取各分量
r = (value >> 16) & 0xFF
g = (value >> 8) & 0xFF
b = value & 0xFF
return (r, g, b)
print(hex_to_rgb("#FF8000")) # (255, 128, 0)
print(hex_to_rgb("#3498DB")) # (52, 152, 219)
# 颜色混合(简单平均)
def blend_colors(color1, color2, ratio=0.5):
"""混合两种颜色"""
r1, g1, b1 = color1
r2, g2, b2 = color2
r = int(r1 * (1 - ratio) + r2 * ratio)
g = int(g1 * (1 - ratio) + g2 * ratio)
b = int(b1 * (1 - ratio) + b2 * ratio)
return (r, g, b)
# 颜色变亮/变暗
def brighten(color, factor=1.2):
"""提亮颜色"""
r, g, b = color
r = min(255, int(r * factor))
g = min(255, int(g * factor))
b = min(255, int(b * factor))
return (r, g, b)
def darken(color, factor=0.8):
"""变暗颜色"""
r, g, b = color
r = max(0, int(r * factor))
g = max(0, int(g * factor))
b = max(0, int(b * factor))
return (r, g, b)
base_color = (100, 150, 200)
print(f"原色: {base_color}")
print(f"提亮: {brighten(base_color)}")
print(f"变暗: {darken(base_color)}")
六、位运算实战:状态标记与位图
class UserStatus:
"""用户状态标记系统(用一个整数表示多种状态)"""
ONLINE = 1 << 0 # 在线
VERIFIED = 1 << 1 # 已验证
PREMIUM = 1 << 2 # 会员
BANNED = 1 << 3 # 被封禁
MODERATOR = 1 << 4 # 版主
@classmethod
def is_online(cls, status):
return (status & cls.ONLINE) != 0
@classmethod
def set_online(cls, status):
return status | cls.ONLINE
@classmethod
def set_offline(cls, status):
return status & (~cls.ONLINE)
@classmethod
def describe(cls, status):
"""描述用户状态"""
labels = []
for attr in ['ONLINE', 'VERIFIED', 'PREMIUM', 'BANNED', 'MODERATOR']:
flag = getattr(cls, attr)
if status & flag:
labels.append(attr)
return labels if labels else ['NONE']
# 批量处理用户状态的位图
class UserBitmap:
"""使用位图追踪大量用户的在线状态"""
def __init__(self, max_users=1024):
# 每个整数存储64个用户的位
self.bitmap_size = (max_users + 63) // 64
self.bitmap = [0] * self.bitmap_size
def set_online(self, user_id):
"""设置用户在线"""
word_idx = user_id // 64 # 在哪个整数
bit_idx = user_id % 64 # 在那个整数的哪一位
self.bitmap[word_idx] |= (1 << bit_idx)
def set_offline(self, user_id):
"""设置用户离线"""
word_idx = user_id // 64
bit_idx = user_id % 64
self.bitmap[word_idx] &= ~(1 << bit_idx)
def is_online(self, user_id):
"""检查用户是否在线"""
word_idx = user_id // 64
bit_idx = user_id % 64
return (self.bitmap[word_idx] & (1 << bit_idx)) != 0
def online_count(self):
"""在线用户总数(利用位运算快速统计)"""
total = 0
for word in self.bitmap:
total += word.bit_count() # Python 3.8+的bit_count方法
return total
# 使用
bitmap = UserBitmap(1024)
bitmap.set_online(1)
bitmap.set_online(100)
bitmap.set_online(500)
print(f"用户1在线: {bitmap.is_online(1)}")
print(f"用户2在线: {bitmap.is_online(2)}")
print(f"在线总数: {bitmap.online_count()}")
七、位运算的性能优势
import timeit
# 乘除2的幂 vs 移位
n = 1234567890
# 乘法 vs 左移
t_multiply = timeit.timeit(lambda: n * 64, number=10_000_000)
t_shift = timeit.timeit(lambda: n << 6, number=10_000_000)
print(f"n * 64: {t_multiply:.4f}s")
print(f"n << 6: {t_shift:.4f}s")
print(f"移位比乘法快: {t_multiply / t_shift:.1f}x")
# 除法 vs 右移
t_divide = timeit.timeit(lambda: n // 64, number=10_000_000)
t_rshift = timeit.timeit(lambda: n >> 6, number=10_000_000)
print(f"n // 64: {t_divide:.4f}s")
print(f"n >> 6: {t_rshift:.4f}s")
print(f"移位比除法快: {t_divide / t_rshift:.1f}x")
# 取模2的幂 vs 位与
t_modulo = timeit.timeit(lambda: n % 64, number=10_000_000)
t_bitand = timeit.timeit(lambda: n & 63, number=10_000_000)
print(f"n % 64: {t_modulo:.4f}s")
print(f"n & 63: {t_bitand:.4f}s")
print(f"位与比取模快: {t_modulo / t_bitand:.1f}x")
# 奇偶判断
t_mod2 = timeit.timeit(lambda: n % 2 == 0, number=10_000_000)
t_and1 = timeit.timeit(lambda: n & 1 == 0, number=10_000_000)
print(f"n % 2 == 0: {t_mod2:.4f}s")
print(f"n & 1 == 0: {t_and1:.4f}s")
print(f"位与比取模快: {t_mod2 / t_and1:.1f}x")
八、位运算的常用技巧速查
# ===== 位运算常用技巧 =====
# 1. 判断奇偶
def is_even(n):
return (n & 1) == 0
def is_odd(n):
return (n & 1) == 1
# 2. 乘以/除以 2 的幂
mul_8 = n << 3 # n * 8
div_8 = n >> 3 # n // 8
mod_8 = n & 7 # n % 8
# 3. 获取/设置/清除第k位
def get_kth_bit(n, k):
return (n >> k) & 1
def set_kth_bit(n, k):
return n | (1 << k)
def clear_kth_bit(n, k):
return n & ~(1 << k)
# 4. 清除最低位的1
def clear_lowest_set_bit(n):
"""清除最低位的1(Brian Kernighan算法)"""
return n & (n - 1)
# 5. 获取最低位的1
def get_lowest_set_bit(n):
return n & (-n)
# 6. 统计二进制中1的个数
def count_ones(n):
# Python 3.8+直接用 int.bit_count()
return n.bit_count()
# 手动方法:
# count = 0
# while n:
# n &= n - 1
# count += 1
# return count
# 7. 判断是否为2的幂
def is_power_of_two(n):
return n > 0 and (n & (n - 1)) == 0
# 8. 将最低位的0变为1
def set_lowest_zero_bit(n):
return n | (n + 1)
# 验证
print(is_even(10)) # True
print(is_odd(10)) # False
print(get_kth_bit(0b1010, 3)) # 1
print(set_kth_bit(0b1000, 1)) # 10 (0b1010)
print(clear_kth_bit(0b1111, 1)) # 13 (0b1101)
print(clear_lowest_set_bit(0b1100)) # 8 (0b1000)
print(get_lowest_set_bit(0b1100)) # 4 (0b100)
print(count_ones(0b10110110)) # 5
print(is_power_of_two(16)) # True
print(is_power_of_two(18)) # False
九、实战案例:IP地址与子网掩码计算
class IPCalculator:
"""IP地址与子网掩码计算工具"""
@staticmethod
def ip_to_int(ip_str):
"""IP地址字符串转整数"""
parts = ip_str.split('.')
ip_int = 0
for part in parts:
ip_int = (ip_int << 8) | int(part)
return ip_int
@staticmethod
def int_to_ip(ip_int):
"""整数转IP地址字符串"""
parts = []
for i in range(4):
parts.append(str((ip_int >> (24 - i * 8)) & 0xFF))
return '.'.join(parts)
@staticmethod
def get_network_address(ip, subnet_mask):
"""计算网络地址"""
ip_int = IPCalculator.ip_to_int(ip)
mask_int = IPCalculator.ip_to_int(subnet_mask)
network_int = ip_int & mask_int
return IPCalculator.int_to_ip(network_int)
@staticmethod
def get_broadcast_address(ip, subnet_mask):
"""计算广播地址"""
ip_int = IPCalculator.ip_to_int(ip)
mask_int = IPCalculator.ip_to_int(subnet_mask)
# 广播地址 = 网络地址 | (~掩码 的低32位)
broadcast_int = (ip_int & mask_int) | (~mask_int & 0xFFFFFFFF)
return IPCalculator.int_to_ip(broadcast_int)
@staticmethod
def get_host_count(subnet_mask):
"""计算可用主机数"""
mask_int = IPCalculator.ip_to_int(subnet_mask)
# 主机数 = 2^(32-前缀长度) - 2
prefix_len = mask_int.bit_count()
return (1 << (32 - prefix_len)) - 2
@staticmethod
def is_same_network(ip1, ip2, subnet_mask):
"""判断两个IP是否在同一子网"""
return IPCalculator.get_network_address(ip1, subnet_mask) == \
IPCalculator.get_network_address(ip2, subnet_mask)
# 使用演示
ip = "192.168.1.100"
mask = "255.255.255.0"
print(f"IP地址: {ip}")
print(f"子网掩码: {mask}")
print(f"IP整数: {IPCalculator.ip_to_int(ip)}")
print(f"网络地址: {IPCalculator.get_network_address(ip, mask)}")
print(f"广播地址: {IPCalculator.get_broadcast_address(ip, mask)}")
print(f"可用主机数: {IPCalculator.get_host_count(mask)}")
ip2 = "192.168.1.200"
print(f"{ip} 与 {ip2} 在同一子网: "
f"{IPCalculator.is_same_network(ip, ip2, mask)}")
ip3 = "192.168.2.1"
print(f"{ip} 与 {ip3} 在同一子网: "
f"{IPCalculator.is_same_network(ip, ip3, mask)}")
十、本章小结
本文我们从二进制基础开始,系统学习了Python的所有位运算符:
- 按位与
&:两位都为1才是1。常用于位检查、掩码操作、权限验证。 - 按位或
|:任一位为1就是1。常用于位设置、标志合并。 - 按位异或
^:两位不同得1。常用于位翻转、无临时变量交换、找奇数次出现的数。 - 按位取反
~:~n = -(n+1)。Python中用补码表示。 - 左移
<<:n << k = n * 2^k。常用于快速乘法、创建掩码。 - 右移
>>:n >> k = n // 2^k。常用于快速除法、提取位。 - 实战应用:权限系统、颜色处理、状态标记、IP地址计算——位运算在这些场景中简洁高效。
位运算虽然看起来"底层",但掌握它意味着你能写出更高效的代码,也能更好地理解计算机的工作原理。当你看到permission & READ这样的代码时,你不再困惑,而是会心一笑——这就是位运算的魅力。
到此这篇关于Python基础指南之位运算符与二进制运算入门详解的文章就介绍到这了,更多相关Python运算符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
pytorch中的named_parameters()和parameters()
这篇文章主要介绍了pytorch中的named_parameters()和parameters()使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-09-09
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
这篇文章主要介绍了基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-07-07
解决python3.6 右键没有 Edit with IDLE的问题
这篇文章主要介绍了解决python3.6 右键没有 Edit with IDLE的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2021-03-03


最新评论