CC++ & Algorithm

Python按位与 & 和按位或 |

困难3
语言版本:C++Python
概述:按位与和按位或像两把开关,分别控制灯泡:与需要两个都闭合才亮,或只要一个闭合就亮。

按位与 & 和按位或 | —— 用二进制开关控制数字的每一位

计算机里所有数字最终都变成由0和1组成的二进制数。按位与(&)和按位或(|)就是直接对二进制数的每一位进行“开关操作”。你可以把它们想象成两套控制灯泡的开关:按位与需要两个开关都闭合才亮,而按位或只要有一个开关闭合就亮。掌握它们,你就能像搭积木一样灵活地处理数字的二进制位。

什么是按位与?—— 两个开关串联

你房间里有一盏灯,它和两个开关串联:只有两个开关都打开,灯才亮。如果有一个开关关着,电流就过不去,灯就不亮。按位与的规则完全一样:

  • 两个位都是1,结果才是1
  • 只要有一个是0,结果就是0

我们把两个数的二进制位从右到左(从最低位到最高位)对齐,一位一位地计算。如果两个数的位数不同,短的数左边补0。

例子:计算 5 & 3

5 的二进制是 101(4+0+1),3 的二进制是 011(0+2+1)。从右往左对齐:

  1 0 1
& 0 1 1
--------
  0 0 1
  • 最右边:1 和 1 → 1 ✔
  • 中间:0 和 1 → 0 ✘
  • 左边:1 和 0 → 0 ✘

结果二进制 001,也就是十进制 1

生活中的“与”例子

小明的妈妈规定:只有做完作业并且吃完晚饭,才能看电视。两个条件都满足(都是1)→ 看电视(结果为1);少一个条件(有一个0)→ 不能看(结果为0)。这就是按位与的思想。

什么是按位或?—— 两个开关并联

现在换一种接线方式:两个开关并联。只要有一个开关闭合,灯就会亮;只有两个都断开,灯才熄灭。按位或的规则:

  • 两个位中只要有一个是1,结果就是1
  • 两个都是0,结果才是0

例子:计算 5 | 3

还是用5和3:

  1 0 1
| 0 1 1
--------
  1 1 1
  • 最右边:1 或 1 → 1 ✔
  • 中间:0 或 1 → 1 ✔
  • 左边:1 或 0 → 1 ✔

结果二进制 111,也就是十进制 7

生活中的“或”例子

学校规定:只要语文成绩或者数学成绩达到90分,就能获得进步奖。一个达到(1)→ 获奖(1);两个都达到(1和1)也获奖;只有两个都没达到(0和0)才不获奖。这就是按位或。

为什么位运算很有用?

位运算可以直接操作数字的二进制表示,处理速度比普通算术运算更快(计算机底层就是二进制)。常见用途包括:

  • 权限控制:用二进制位表示不同的权限,通过按位与检查是否拥有某权限
  • 设置或清除标志位:例如游戏中的角色状态(是否中毒、是否隐身)
  • 优化性能:某些数学运算(如乘2、除2)可以用移位代替

新手最容易犯的4个错误

错误1:把位运算符和逻辑运算符搞混

  • 位运算:&|^~ —— 操作的是二进制位,结果是一个整数
  • 逻辑运算:andornot —— 操作的是布尔值(True/False),结果也是布尔值
# 正确
a = 5   # a是整数
b = 3
print(a & b)   # 结果是整数1

# 错误:把&当成了and
if a & b:      # 这相当于 if 1: ,会执行,但不是判断两个条件
    print("两个数字的位都是1?")  # 实际上只检查了按位与结果是否为0

错误2:忘记二进制对齐

位数不同的数字,左边补0再运算。例如 2 & 6
2的二进制10,6的二进制110,对齐后2是010,按位与得010即2。

错误3:认为按位与的结果永远是0或1

两个数字的每一位进行与运算,结果是一个新的二进制数,不一定只是0或1。例如 12 & 10 = 8(二进制1000),是一个完整的数字。

错误4:优先级搞错

位运算符的优先级比比较运算符低,比算术运算符也低。比如 a & b + 1 会先算 b+1 再与 a 进行位运算。建议用括号明确顺序。

完整可运行的示例程序

下面这个程序让你输入两个整数,并打印它们的二进制表示和位运算结果。每一行变量定义都写了中文注释,方便理解。

# 让用户输入两个整数
num1 = int(input("请输入第一个整数: "))   # 比如 5
num2 = int(input("请输入第二个整数: "))   # 比如 3

# 计算位运算结果
and_result = num1 & num2   # 按位与
or_result  = num1 | num2   # 按位或

# 用内置bin()函数把数字变成二进制字符串(去掉开头的'0b')
bin1 = bin(num1)[2:]       # 去掉前缀,比如 '101'
bin2 = bin(num2)[2:]
bin_and = bin(and_result)[2:]
bin_or  = bin(or_result)[2:]

# 打印结果,并显示二进制形式
print(f"{num1} 的二进制是 {bin1}")
print(f"{num2} 的二进制是 {bin2}")
print("-" * 20)
print(f"{num1} & {num2} = {and_result}  (二进制 {bin_and})")
print(f"{num1} | {num2} = {or_result}  (二进制 {bin_or})")

运行示例(输入5和3):

请输入第一个整数: 5
请输入第二个整数: 3
5 的二进制是 101
3 的二进制是 11
--------------------
5 & 3 = 1  (二进制 1)
5 | 3 = 7  (二进制 111)

你可以试试输入12和10,看看结果是否和之前一样。

更多动手练习

  1. 计算 6 | 9 并手写二进制过程,再用Python验证。
  2. 思考:a & 1 的结果是什么?提示:1的二进制只有最低位是1,所以a & 1就是取出a的最低位(0表示偶数,1表示奇数)。试试看!
  3. 为什么 255 & 15 的结果是15?提示:255的二进制是11111111,15是00001111,按位与保留低4位。

接下来可以学什么?

  • 按位异或 ^:相同为0,不同为1,常用于交换两个数或加密。
  • 按位取反 ~:把0变1,1变0,结果是原数的补码形式。
  • 左移 <<和右移 >>:相当于乘以2或除以2,效率很高。
  • 权限管理示例:用位运算设计一个简单的文件权限系统(读、写、执行)。

掌握了按位与和按位或,你就拥有了一把直接操作二进制位的钥匙。试着把生活中的“条件判断”转化成二进制运算,你会发现编程世界又多了一层奇妙的理解!

例题精讲

1单选题

在Python中,表达式 5 & 3 的结果是多少?

A0
B1
C2
D7
2填空题
执行以下Python代码后,输出结果是什么?
print(6 | 9)
请填写输出值:___
3判断题

在Python中,按位与运算符(&)的优先级高于按位或运算符(|)。

4填空题
已知在Python交互环境中执行以下代码后,x的值是多少?
x = 0b1010 & 0b1100
请填写x的十进制值:___
5单选题

下列哪个Python表达式的运算结果为0?

A1 & 2
B1 | 2
C3 & 3
D0 | 1