数制与数据表示
一句话模型
计算机只保存有限长度的二进制位,数制决定位的权值,数据类型决定如何解释同一串位模式,运算电路负责变换这些位,并通过标志位说明结果是否为零、进位或溢出。
三层递进
- 简单:先建立二、八、十、十六进制之间的表示和转换关系。
- 中等:加入无符号数、补码和 IEEE 754,理解有限位模式如何解释为整数或浮点数。
- 复杂:叠加加减运算、位宽转换、溢出、舍入和状态标志,追踪“数值 → 编码 → 运算 → 解释”的完整流程。
简单图谱:数制与位模式
数制的核心是“每一位的权值”。二进制适合硬件存储,八进制和十六进制可以按三位、四位二进制直接分组,十进制则需要通过按权展开、除基取余或乘基取整进行转换。
# 数制与数据表示
## 进位计数制
- 基数:每一位可使用的数字个数
- 位权:第 i 位的权值为基数的 i 次幂
- 二进制、八进制、十进制、十六进制
- 整数:除基取余
- 小数:乘基取整
## 二进制位模式的解释
- 无符号整数:所有位表示数值
- 补码整数:最高位权值为负
- 浮点数:符号、阶码、尾数
- BCD:每四位表示一个十进制数字
中等图谱:同一位模式的不同解释
主干问题是:内存中的一串 0 和 1 为什么可以表示完全不同的数值?
以 8 位位模式 1111 1111 为例:
- 按无符号整数解释,它是 (255)。
- 按补码有符号整数解释,它是 (-1)。
- 按两个 BCD 数字解释,它不是合法的 8421 BCD 编码,因为每组
1111都超过十进制数字 9。 - 位模式本身没有类型,类型决定各位的权值和合法编码范围。
复杂图谱:从数值到运算结果
复杂图把表示与运算连接起来:输入数值先编码为固定位宽,运算电路处理位模式,再由类型规则和标志位解释结果。整数关注截断与溢出,浮点数还要处理对阶、规格化和舍入。
阅读时沿三条路径追踪:
- 整数路径:选择位宽和有无符号 → 编码 → 加减/移位 → 检查 CF、OF、ZF、SF。
- 浮点路径:十进制实数转二进制 → 规格化 → 编码
s/exp/frac→ 对阶运算 → 规格化和舍入。 - 类型转换路径:保持位模式重新解释,或改变位宽/类型后进行符号扩展、零扩展、截断和舍入。
子模块图谱:整数与补码
补码把减法转换成加法,使同一套加法器既能处理无符号数,也能处理有符号数。区别不在加法器,而在结果如何解释以及查看 CF 还是 OF。
整数子图的阅读顺序是:确定位宽 → 选择有符号/无符号解释 → 正数直接编码、负数取反加一 → 加法器运算 → 根据类型判断进位或溢出。
子模块图谱:IEEE 754 浮点数
IEEE 754 用符号位、偏置阶码和尾数表示范围很大的实数,同时保留 ±0、非正规数、±∞ 和 NaN 等特殊编码。
浮点子图的阅读顺序是:判断符号 → 把二进制实数规格化 → 阶码加 Bias → 保存小数部分 → 根据 exp/frac 区分正常值、非正规数和特殊值。
关键问题
位模式和数值为什么不能混为一谈?
位模式只是存储的二进制序列;无符号、补码、浮点或 BCD 等解释规则为每一位赋予不同含义。同一位模式在不同类型下可以对应不同数值。
补码为什么能统一加法和减法?
在固定位宽下,补码运算等价于模 (2^n) 运算,减去 (B) 可以转化为加上 ~B + 1,超出位宽的最高进位直接舍弃。
CF 和 OF 有什么区别?
CF 描述无符号运算是否产生最高位进位或借位,OF 描述补码有符号结果是否超出表示范围。同一加法结果可能 CF 与 OF 不同。
为什么浮点数会有误差?
许多十进制小数在二进制中无限循环,而尾数位数有限,只能舍入为邻近的可表示值;浮点加减还可能因对阶丢失低位精度。
旁路清单
- 数制转换:按权展开、除基取余、乘基取整、二进制分组
- 整数编码:原码、反码、补码、移码和 BCD
- 位宽变化:零扩展、符号扩展、高位截断
- 整数运算:加减、逻辑移位、算术移位、乘除
- 标志位:ZF、SF、CF、OF 的计算和使用边界
- 浮点表示:Bias、隐藏位、正常值、非正规数、无穷和 NaN
- 浮点运算:对阶、尾数运算、规格化、舍入和溢出
- 类型转换:有符号/无符号、整数/浮点、宽类型/窄类型