⚙️ 第二章 用二进制来理解数据
📄 一句话概括

逻辑运算只有三种常用动作——与(挑)、或(置)、异或(翻);配好掩码,想动哪一位就动哪一位。

📝 本节和前面几节的关系

2.5 讲完了移位,这一节补位操作的另一个工具箱:逻辑运算。

一、三种基本运算

与 AND:逐位比较,两个都是 1 结果才是 1。 或 OR:逐位比较,有一个是 1 结果就是 1。 异或 XOR:逐位比较,两个不同结果才是 1。 再加上非 NOT(一位取反),就是全部家底了——真值表只有四行,一眼能看完。

二、配掩码的三件事

单独用它们没意义,关键是把运算和一个【掩码】配起来用: 挑出某几位 → 与一个【那几位是 1、其余是 0】的掩码。 把某几位置 1 → 或一个【那几位是 1、其余是 0】的掩码。 把某几位翻转 → 异或一个【那几位是 1、其余是 0】的掩码。 一句话记法:与用 0 清、或用 1 置、异或用 1 翻。

三、为什么叫【窍门】

教材用【窍门】这个词是有道理的:这三种运算本身极简单,值钱的是【怎么选掩码】。 写法上有个习惯:先把你想要的结果写出来,再倒推掩码——比硬记结论快得多。 另一个好用的判断:与运算里,1 位是保持、0 位是清零。记住这句,掩码基本不会选错。

四、这些运算是给谁用的

给硬件用:CPU 的指令里就有一整套逻辑运算,位运算指令执行得极快。 给程序用:权限标志、状态位、颜色通道、网络协议头,全都在用位来省空间。 例:一个字节存 8 个开关状态,取出第 3 个开关,就是用掩码 0000 1000 去与一下。

五、动手 Demo:逻辑运算的三件常用工具

与(AND)挑出某几位,或(OR)置上某几位,异或(XOR)翻转某几位。 三种运算配一个掩码,就能精确操作任意一位。

v = 0b10110110
print("样本      ", format(v, "08b"))
print("取低 4 位 ", format(v & 0x0F, "08b"), "  与 0000 1111")
print("清零第 1 位", format(v & ~0b10 & 0xFF, "08b"), "  与 1111 1101")
print("低 4 位置1", format(v | 0x0F, "08b"), "  或 0000 1111")
print("翻转低 4 位", format(v ^ 0x0F, "08b"), "  异或 0000 1111")

实跑输出:

--------------------------------------------------------------------
逻辑运算的三件常用工具
--------------------------------------------------------------------

**与(AND)用来挑出某几位,或(OR)用来置上某几位,异或(XOR)用来翻转某几位。**
三种运算配一个【掩码】,就能精确操作任意一位。

  样本取 1011 0110:

  目的                用什么运算             掩码          结果
  ------------------------------------------------------------------
  取低 4 位           与 AND                 0000 1111     00000110
  只留高 4 位         与 AND                 1111 0000     10110000
  把低 4 位全置 1     或 OR                  0000 1111     10111111
  翻转低 4 位         异或 XOR               0000 1111     10111001
  把第 1 位清零       与 AND(掩码取反)     1111 1101     10110100

  记法很简单:
    与 AND   一位一位比,两个都是 1 才是 1      -> 挑、清
    或 OR    有一位是 1 就是 1                  -> 置
    异或 XOR 两位不同才是 1                     -> 翻
  **只要选对掩码,想动哪一位就动哪一位,别的位一根毫毛都不碰。**

与用 0 清、或用 1 置、异或用 1 翻——三种动作配三种掩码。 只要掩码选对,想动哪一位就动哪一位,其他位一根毫毛都不碰。

30 秒实验

  1. 一个字节存 8 个开关,写出【打开第 3 个】和【读出第 5 个】各用什么掩码。
  2. 用异或做个小实验:同一个掩码异或两次,结果会回到原值吗?

常见误区

  1. 以为逻辑运算只是【布尔代数那一套】。它在硬件里是逐位并行执行的,一次处理 8 位、32 位。
  2. 硬背结论不记掩码思路。想清【要留哪几位】,掩码自然就出来了。
自测三问(点开对答案) 1. 三种基本逻辑运算分别适合做什么? —— 与用于挑出(或清零)某些位,或用于把某些位置 1,异或用于翻转某些位。 2. 与运算里掩码的 1 和 0 各代表什么? —— 1 代表保持原值,0 代表把这一位清零。 3. 为什么说这三种运算值得好好掌握? —— 硬件执行极快,程序里用位标志、颜色、协议字段都靠它省空间、提速度。

相关笔记