# G3-18 课后练习 —— 位运算实战
> **GESP等级：三级 | 考级考点：GESP Python 三级**

**姓名：__________  日期：__________**

---

## 家长小课堂

亲爱的家长您好！今天孩子学习了**位运算的实战应用**——用位运算解决实际问题。

**核心知识点：**

| 实战技巧 | 表达式 | 说明 | 用途 |
|---------|--------|------|------|
| 判断奇偶 | n & 1 | 1=奇数, 0=偶数 | 比 n%2 快 |
| 判断相等 | (a^b)==0 | 成立则相等 | 比 a==b 底层 |
| 交换数值 | a^=b;b^=a;a^=b | 三步交换 | 不用第三变量 |
| 掩码取位 | n & ((1<<k)-1) | 取末k位 | RGB颜色提取 |
| 快速乘除 | n<<k / n>>k | 乘/除2的k次方 | 比 */ 快 |
| 判断2的幂 | n&(n-1)==0 | 成立则2的幂 | 经典面试题 |

**记忆口诀：** 
"奇偶判断用与1，三步异或交换法，掩码面具只露想看，左移乘右移除，一刀砍掉最高位"
"末位警察看一看，1奇0偶一瞬间！"
"异或异或，相同归零，不同留1！"
"三步异或真奇妙，不用帮手就换好！"
"掩码一剪咔咔咔，末k位全留下！"
"左移×2上楼梯，右移÷2下楼梯！"
"独生子女只有1个1，一把剪刀剪光光！"

建议家长用15分钟陪孩子完成下面练习，可以和孩子一起做"身体锚点"动作！

---

## 基础练习

### 1. 选择题（每题3分，共15分）

(1) 判断一个数是奇数还是偶数，应该用哪个表达式？
   A. n & 0    B. n & 1    C. n | 1    D. n ^ 1

(2) 用位运算判断两个数相等，应该用哪个表达式？
   A. a & b == 0    B. a | b == 0
   C. (a ^ b) == 0  D. (a ^ b) == 1

(3) 掩码 (1 << 4) - 1 等于多少？
   A. 4    B. 15    C. 16    D. 31

(4) 下列哪个数满足 n & (n-1) == 0？
   A. 6    B. 7    C. 8    D. 9

(5) 32 >> 3 等于多少？
   A. 2    B. 4    C. 8    D. 16

### 2. 计算题（每题2分，共10分）

```
(1) 13 & 1 = ____   判断：____数
(2) (10 ^ 10) == 0  ->  True/False？  ____
(3) 255 & 0b1111 = ____
(4) 12 & (12-1) = ____  12是2的幂吗？____
(5) 7 << 4 = ____    (7x16)
```

### 3. 填空题（每空1分，共12分）

```
(1) 判断奇偶的公式：if n ____ 1: 奇数
(2) 判断相等的公式：if (a ____ b) == 0: 相等
(3) 交换a和b的三步：
    a ____= b
    b ____= a
    a ____= b
(4) 提取n的最后k位：n & ((1 ____ k) ____ 1)
(5) n * 16 = n ____ 4
(6) n // 32 = n ____ 5
(7) 判断2的幂：n > 0 and (n & (n ____ 1)) == ____
```

---

## 闯关练习

### 第1关：把下面代码中的____补全（每空2分，共10分）

```python
# 程序：位运算工具箱

def is_odd(n):
    """判断奇数"""
    return ____ & ____  # 填入正确的表达式

def is_power_of_two(n):
    """判断2的幂"""
    return n > 0 and (____ & (____ - 1)) == ____

def last_k_bits(n, k):
    """提取n的最后k位"""
    mask = (____ << k) - ____  # 生成掩码
    return n & mask

# 测试
print(is_odd(5))      # 期待 True
print(is_odd(10))     # 期待 False
print(is_power_of_two(16))  # 期待 True
print(is_power_of_two(20))  # 期待 False
print(last_k_bits(213, 3))  # 期待 5
```

### 第2关：颜色编码实战（每空2分，共10分）

你的生日颜色：#RRGGBB，R=生日月份，G=生日日期，B=月份+日期

```
你的生日：____月____日
R = ____, G = ____, B = ____ (月份+日期)

组合成颜色值：
color = (R << 16) | (G << 8) | B
color = 0x______

用Python验证：
>>> color = 0x______
>>> R = (color >> 16) & 0xFF
>>> G = (color >> 8) & 0xFF
>>> B = color & 0xFF
>>> print(f"R={R}, G={G}, B={B}")
```

### 第3关：编程实践（每题4分，共12分）

写Python代码解决以下问题：

```python
# 题目1：用位运算判断用户输入的数字是奇数还是偶数
n = int(input("请输入一个数字: "))
if ____:  # 用位运算
    print(f"{n} 是奇数")
else:
    print(f"{n} 是偶数")

# 题目2：打印1-100中所有2的幂
print("2的幂有:")
for n in range(1, 101):
    if ____:  # 判断2的幂
        print(n, end=" ")
print()

# 题目3：提取颜色值的RGB分量
color = 0xFF8800
R = ____  # 提取红色通道
G = ____  # 提取绿色通道
B = ____  # 提取蓝色通道
print(f"R={R}, G={G}, B={B}")  # 期待 R=255, G=136, B=0
```

---

## 身体锚点家庭互动

### 活动1：我是小老师（5分钟）

请你教会爸爸妈妈6大位运算的身体动作！

| 绝招 | 身体动作 | 教会了吗？ |
|------|----------|-----------|
| 判断奇偶 | 右手比1看末位，左手伸1指/握拳 | ☐ |
| 判断相等 | 双臂交叉→向下挥开 | ☐ |
| 异或交换 | 左手拉右手转三圈 | ☐ |
| 取末k位 | 左伸k指，右剪刀咔嚓 | ☐ |
| 快速乘除 | 身体左跳变大/右蹲变小 | ☐ |
| 判断2的幂 | 竖1根食指 | ☐ |


### 活动2：全家总动员——位运算动作操

全家站成一排，家长喊题目，大家一起做动作！

```
家长喊："15是奇数还是偶数？"
全家做：右手比1，左手伸1指 → "奇数！"

家长喊："5和5相等吗？"
全家做：双臂交叉→向下挥开 → "相等！"

家长喊："怎么交换a和b？"
全家做：左手拉右手转三圈 → "三步完成！"

家长喊："取末4位怎么做？"
全家做：左伸4指，右剪刀咔嚓 → "掩码！"

家长喊："3左移2位！"
全家做：身体向左跳两下 → "12！"

家长喊："8是2的幂吗？"
全家做：竖1根食指 → "是！"
```

**记录：** 全家一起做了____分钟，笑声____次 😊

---

## 实践任务

### 任务1：家庭编码游戏

用位运算设计一个"猜数字"游戏（和爸爸妈妈一起玩）：

1. 你心里想一个1-15之间的数
2. 用下面的4个问题，让爸妈猜
3. 每个问题用 & 运算来检查一个二进制位

```
你想的数字 = ____（不要告诉爸妈）

Q1：你的数 & 1 等于0吗？ 答案：____
Q2：你的数 & 2 等于0吗？ 答案：____
Q3：你的数 & 4 等于0吗？ 答案：____
Q4：你的数 & 8 等于0吗？ 答案：____

爸妈猜的数 = ____  ✓/✗
```

**原理：** 这就像用4个"是/否"问题猜数字！
（二进制有4位，每一位问一次）

### 任务2：我的颜色调色板

用位运算创建你自己的颜色调色板：

```python
# 选择你最喜欢的3种颜色
colors = [
    ("颜色1名称", 0x______),  # 填入十六进制值
    ("颜色2名称", 0x______),
    ("颜色3名称", 0x______),
]

# 提取每个颜色的RGB
for name, color in colors:
    R = (color >> 16) & 0xFF
    G = (color >> 8) & 0xFF
    B = color & 0xFF
    print(f"{name}: #{color:06X} -> R={R}, G={G}, B={B}")
```

**我的颜色板：**
- 颜色1：____ = #______ = R=___, G=___, B=___
- 颜色2：____ = #______ = R=___, G=___, B=___
- 颜色3：____ = #______ = R=___, G=___, B=___

---

## 拓展思考（选做）

### 思考题1：为什么位运算更快？

从CPU的角度思考：
- 普通加法/乘法：CPU需要经过复杂的电路运算
- 位运算：CPU直接操作寄存器中的二进制位

结论：位运算是CPU的"本能"，就像你眨眼睛一样快！

### 思考题2：用位运算实现集合操作

```python
# 用二进制位表示集合
# 第0位=元素0在位，第1位=元素1在位...

A = 0b101010  # 集合 {1, 3, 5}
B = 0b110011  # 集合 {0, 1, 4, 5}

# 交集（同时在A和B中的元素）
intersection = A & B
print(f"交集: {bin(intersection)}")  # 包含?

# 并集（在A或B中的元素）
union = A | B
print(f"并集: {bin(union)}")

# 补集（在A不在B中的元素）
difference = A & ~B
print(f"差集: {bin(difference)}")
```

**问题：** 交集的结果 0b100010 表示哪些元素？
答：第____位和第____位是1，所以包含元素{____, ____}

### 思考题3：如果不用位运算...

如果让你不用位运算，而是用普通的加减乘除来实现：
1. 判断奇偶：你会怎么做？________
2. 交换两个数：你会怎么做？________
3. 判断2的幂：你会怎么做？________

对比一下，位运算是不是更简洁、更快速？

---

## 本阶段总结

第18阶段《进制与位运算》全部学完了！现在你可以：

| 技能 | 掌握程度 |
|------|---------|
| 理解二进制只有0和1 | /5 |
| 二进制与十进制互转 | /5 |
| 了解八进制和十六进制 | /5 |
| 使用Python进制函数 | /5 |
| 6种位运算规则 | /5 |
| 位运算实战技巧 | /5 |

**最让你印象深刻的知识点是什么？**
答：________________________________

**你觉得最难的是什么？**
答：________________________________

---


我已了解今天的学习内容，并陪伴孩子完成了课后练习。


---

---

**自我评价：** □ 全都会了  □ 大部分会了  □ 还要再练练