位运算基础
位运算让一个整数保存多项标志、权限或打包字段。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 的完整规则。
- AND:从位 7 扫到位 0,只留下双方都为 1 的列,得到
00100100 = 36。 - OR:任一输入为 1 就保留,得到
11110111 = 247。 - XOR:不同为 1,相同为 0,得到
11010011 = 211。 - NOT:忽略 b,翻转 a 的八位,
10110101变为01001010 = 74。 - 检查宽度:在 Python 和 JavaScript 中,原始
~181都是-182。-182 & 0b11111111使用同样的 AND 规则选择低八位,结果才是01001010 = 74。 - 左移一位:原位 7 越界丢弃,位 0 补 0,加掩码后得到
01101010 = 106。 - 右移一位:原位 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,不模拟算术右移或符号扩展。