CC++ & Algorithm

Python按位异或 ^ 和按位取反 ~

较难6
语言版本:C++Python
概述:异或像两个小朋友对答案:不一样才举手;取反像照镜子,0变1,1变0,但Python里会多一个负号。

不一样的“找不同”和“照镜子”——Python的按位异或 ^ 和按位取反 ~

位运算就像计算机里的“快速小工具”,能直接操作数字的二进制位。今天我们学习两个特别有意思的工具:按位异或^)和按位取反~)。异或像两个小朋友对答案:不一样才举手;取反像照镜子:0变1,1变0,但Python里会多一个负号。它们能用来加密数据、交换变量、判断数字的正负等,非常神奇!

学会了与(&)和或(|),接下来认识两个好玩的位运算:异或(^)和取反(~)。


按位异或(^)—— 不一样才为1

异或的规则很像“找不同”:两个位 不一样 时结果为1,一样 时结果为0。

  • 0 ^ 0 = 0
  • 1 ^ 1 = 0
  • 0 ^ 1 = 1
  • 1 ^ 0 = 1

? 生活小例子

小明和小红都有两个答题板,一个写0,一个写1。只有当两个人的答案 不一样 时,老师才会点头(结果为1)。如果两人都写0或都写1,老师就摇头(结果为0)。比如:

  • 小明写0,小红写0 → 一样 → 0
  • 小明写1,小红写0 → 不一样 → 1
  • 小明写1,小红写1 → 一样 → 0

这个规则其实就像“判断两个开关状态是否不同”:如果家里客厅灯坏了,要检查两个开关是否一个开、一个关,就可以用异或。

? 二进制计算示例

举个例子:5 ^ 3(二进制 101011

  1 0 1
^ 0 1 1
--------
  1 1 0   (最左边1和0不同⇒1,中间0和1不同⇒1,最右边1和1相同⇒0)

结果是二进制 110,也就是十进制 6。

? 异或的两个“魔法性质”

  1. 一个数和自己异或得0:因为每一位都一样,结果全部变成0。
    7 ^ 7 = 0,就像小明和小红同时写一样的答案,老师从不点头。

  2. 任何数和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

❗ 新手常见错误

  1. 以为 ~5 直接得到 -5:很多同学会想当然地认为取反就是把正数变负数,但实际上是 -6
    错误:~5 = -5
    正确:~5 = -6

  2. 混淆 ~-:取反不是改变正负号,而是把所有位翻转。在Python里,~ 的优先级高于算术运算符,但低于括号,所以写复杂表达式时最好加括号。

  3. 误认为 ~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)
  • ^ 实现不用临时变量交换两个整数(刚刚已经演示过)
  • ^ 找出数组中只出现一次的数字(经典编程题)

继续探索位运算的世界吧,它们会让你的代码跑得更快、更酷!

例题精讲

1单选题

在Python中,已知 a = 5(二进制 0101),b = 3(二进制 0011),则 a ^ b 的结果是?

A6
B4
C2
D1
2判断题

在Python中,~5 的结果是 -5。

3填空题
下面代码使用异或运算交换两个变量a和b的值,请补全代码:
a = 10
b = 20
a = a ^ b
b = a ^ b
a = ___
4单选题

若 x = 7,则表达式 ~x ^ x 的值为?

A-1
B0
C7
D-8
5填空题
以下函数使用异或找出列表中只出现一次的数字(其他数字均出现两次),补全代码:
def find_unique(nums):
    result = 0
    for num in nums:
        result ___ num
    return result