Python按位异或 ^ 和按位取反 ~
较难6不一样的“找不同”和“照镜子”——Python的按位异或 ^ 和按位取反 ~
位运算就像计算机里的“快速小工具”,能直接操作数字的二进制位。今天我们学习两个特别有意思的工具:按位异或(^)和按位取反(~)。异或像两个小朋友对答案:不一样才举手;取反像照镜子:0变1,1变0,但Python里会多一个负号。它们能用来加密数据、交换变量、判断数字的正负等,非常神奇!
学会了与(&)和或(|),接下来认识两个好玩的位运算:异或(^)和取反(~)。
按位异或(^)—— 不一样才为1
异或的规则很像“找不同”:两个位 不一样 时结果为1,一样 时结果为0。
0 ^ 0 = 01 ^ 1 = 00 ^ 1 = 11 ^ 0 = 1
? 生活小例子
小明和小红都有两个答题板,一个写0,一个写1。只有当两个人的答案 不一样 时,老师才会点头(结果为1)。如果两人都写0或都写1,老师就摇头(结果为0)。比如:
- 小明写0,小红写0 → 一样 → 0
- 小明写1,小红写0 → 不一样 → 1
- 小明写1,小红写1 → 一样 → 0
这个规则其实就像“判断两个开关状态是否不同”:如果家里客厅灯坏了,要检查两个开关是否一个开、一个关,就可以用异或。
? 二进制计算示例
举个例子:5 ^ 3(二进制 101 和 011)
1 0 1
^ 0 1 1
--------
1 1 0 (最左边1和0不同⇒1,中间0和1不同⇒1,最右边1和1相同⇒0)
结果是二进制 110,也就是十进制 6。
? 异或的两个“魔法性质”
-
一个数和自己异或得0:因为每一位都一样,结果全部变成0。
7 ^ 7 = 0,就像小明和小红同时写一样的答案,老师从不点头。 -
任何数和0异或都得它自己:因为0的每一位都是0,和0不同就是原数本身。
7 ^ 0 = 7,就像一个人答题,旁边站个只会写0的人,答案完全由第一个人决定。
利用这两个性质,我们可以做很多有趣的事,比如 交换两个变量的值(不需要临时变量)!
a = 5 # 第一个数
b = 3 # 第二个数
a = a ^ b # a变成 5^3 = 6
b = a ^ b # b变成 6^3 = 5(因为6^3=5,其实就是原来的a)
a = a ^ b # a变成 6^5 = 3(因为6^5=3,其实就是原来的b)
print("交换后:a =", a, "b =", b) # 输出:a = 3, b = 5
是不是很神奇?这就像两个人交换手里的零食,不用第三个口袋,靠异或就能完成。
按位取反(~)—— 把0和1互换
取反就像照镜子,把所有位都反过来:0变成1,1变成0。但是Python里的取反有一点特殊,因为它要考虑整个数字的补码表示(计算机存储负数的方式)。简单地说,~x 的结果等于 -x - 1。
例如 ~5:
- 5的二进制是
000...00101(前面有许多0) - 取反后变成
111...11010 - 这个数在计算机里表示 -6(因为负数用补码存储)
你只需要记住这个规律:~x = -x - 1。
? 为什么是 -x - 1?
我们可以用一个更直观的理解:数字在计算机里就像一圈“刻度”,0的对面是-1,1的对面是-2,2的对面是-3……取反就像跳到刻度对面。
所以 ~5 就是跳到5的对面:-5 - 1 = -6。
~(-3) 就是 -3的对面:-(-3) - 1 = 3 - 1 = 2。
❗ 新手常见错误
-
以为
~5直接得到-5:很多同学会想当然地认为取反就是把正数变负数,但实际上是-6。
错误:~5 = -5❌
正确:~5 = -6✅ -
混淆
~和-:取反不是改变正负号,而是把所有位翻转。在Python里,~的优先级高于算术运算符,但低于括号,所以写复杂表达式时最好加括号。 -
误认为
~0为0:~0的结果是-1,不是0!因为0的二进制全是0,取反后全是1,表示 -1。
完整可运行的代码示例
下面是一个综合例子,演示异或和取反的基本用法,以及一个简单加密的小游戏(用异或加密数字)。
# 演示异或和取反
x = 5 # 第一个数
y = 3 # 第二个数
print("--- 基本运算 ---")
print("x ^ y =", x ^ y) # 6
print("x ^ x =", x ^ x) # 0
print("x ^ 0 =", x ^ 0) # 5
print("~x =", ~x) # -6
print("~y =", ~y) # -4
# 用异或交换两个数
a = 10 # 第一个要交换的数
b = 20 # 第二个要交换的数
print("\n--- 交换前:a =", a, "b =", b)
a = a ^ b
b = a ^ b
a = a ^ b
print("--- 交换后:a =", a, "b =", b)
# 简单加密:把数字加上 “密钥” 就能加密,再异或一次就能解密
key = 7 # 加密用的密钥(随便选一个)
secret = 42 # 要加密的秘密数字
encrypted = secret ^ key # 加密:42 ^ 7 = 45
print("\n--- 加密小实验 ---")
print("原始数字:", secret)
print("加密后:", encrypted)
decrypted = encrypted ^ key # 解密:45 ^ 7 = 42
print("解密后:", decrypted)
运行结果:
--- 基本运算 ---
x ^ y = 6
x ^ x = 0
x ^ 0 = 5
~x = -6
~y = -4
--- 交换前:a = 10 b = 20
--- 交换后:a = 20 b = 10
--- 加密小实验 ---
原始数字: 42
加密后: 45
解密后: 42
注意:加密只是最简单的演示,实际加密要用更复杂的方法哦!
相关知识点指引
学会了异或和取反,你就掌握了位运算中最灵活的两个操作。它们经常和 按位与(&)、按位或(|) 一起使用,用来处理标志位、判断奇偶、清零、设置特定位等。如果你对下面这些话题感兴趣,可以继续学习:
- 用
& 1判断一个数是奇数还是偶数(奇数的最低位是1) - 用
~和&清除某些位(比如把第3位变成0) - 用
^实现不用临时变量交换两个整数(刚刚已经演示过) - 用
^找出数组中只出现一次的数字(经典编程题)
继续探索位运算的世界吧,它们会让你的代码跑得更快、更酷!
例题精讲
在Python中,已知 a = 5(二进制 0101),b = 3(二进制 0011),则 a ^ b 的结果是?
在Python中,~5 的结果是 -5。
下面代码使用异或运算交换两个变量a和b的值,请补全代码:
a = 10
b = 20
a = a ^ b
b = a ^ b
a = ___若 x = 7,则表达式 ~x ^ x 的值为?
以下函数使用异或找出列表中只出现一次的数字(其他数字均出现两次),补全代码:
def find_unique(nums):
result = 0
for num in nums:
result ___ num
return result