在大屏或电脑上体验更佳——动画和操作区域更宽敞。
输入

位运算基础

位运算让一个整数保存多项标志、权限或打包字段。AND 用掩码检查位,OR 设置位,XOR 翻转位,移位调整字段位置。本课对齐两个无符号 8 位数,让每项结果都保持在同一边界内。

位运算如何工作

把输入想成两条对齐的打孔带。布尔位运算只看同一列的输入对;第 5 位的值不会改变第 4 位的判断。

一个权限字节可保存八个开关。permissions & READ_MASK 选择目标位,不修改其余标志。颜色或协议中的打包字段也可以先用掩码选位,再移到便于读取的位置。

  • AND:两位都为 1,结果才为 1。
  • OR:任一位为 1,结果就为 1。
  • XOR:两位不同,结果为 1。
  • NOT:只读取一个输入,把 0、1 互换。

移位改变位置:左移朝第 7 位,右移朝第 0 位。越过边界的位丢弃,新空位补 0。

本课采用无符号 8 位模型,范围 0–255,掩码为 11111111。NOT 与左移之后加掩码,保留低八位。

逐步演示

默认 a = 181 = 10110101、b = 102 = 01100110、shift = 1。对齐列涵盖四种输入位对,可以检验 AND、OR、XOR 的完整规则。

  1. AND:从位 7 扫到位 0,只留下双方都为 1 的列,得到 00100100 = 36。
  2. OR:任一输入为 1 就保留,得到 11110111 = 247。
  3. XOR:不同为 1,相同为 0,得到 11010011 = 211。
  4. NOT:忽略 b,翻转 a 的八位,10110101 变为 01001010 = 74。
  5. 检查宽度:在 Python 和 JavaScript 中,原始 ~181 都是 -182。-182 & 0b11111111 使用同样的 AND 规则选择低八位,结果才是 01001010 = 74。
  6. 左移一位:原位 7 越界丢弃,位 0 补 0,加掩码后得到 01101010 = 106。
  7. 右移一位:原位 0 丢弃,位 7 补 0,得到 01011010 = 90。

结果表保留六个答案。布尔运算在固定列内判定,移位改变列的位置,还可能丢失边界信息。

时间与空间复杂度

固定 8 位机器操作的时间、额外空间均为 O(1)。动画逐位扫描是为了展示规则;若位宽为 W,解释性扫描每项布尔操作用 O(W) 时间。

任意精度整数的实际运算成本也可能随存储所需机器字数量增长,不能对任意长度都写 O(1)。

边界情况

  • shift = 0:不移动、不丢弃,也没有补零位置。
  • shift = 8:原八位全部越界,左右移结果都为 00000000。
  • a 与 b 相等:XOR 全 0,AND、OR 都等于输入。
  • a 与 b 互补:AND 全 0,OR 与 XOR 全 1。
  • a = 0 与 a = 255:NOT 在本课八位范围内互换两端值。

常见错误

  • 把移位无条件当乘除二。 必须考虑位宽、符号与截断。左移丢弃高位后,结果可能不等于普通整数乘法。
  • 把移位当循环移位。 <<、>> 不把越界位送回另一端;本课丢弃越界位并补 0。
  • 忘记 NOT 的整数模型。 Python 整数不是八位,~181 为 -182,不是 74。& MASK 与 255 做 AND,才选出低八位。
  • 混淆位号与屏幕方向。 位 7 在左,位 0 在右,按格子上方的编号追踪。

简化范围

处理器常使用 8、16、32、64 位字,不同语言的有符号表示和右移规则不同。本课固定无符号八位,右移总补 0,不模拟算术右移或符号扩展。