3、数据表示与运算基础:定点数、浮点数(IEEE 754)、原码反码补码、字符编码与校验码
计算机体系结构的第一块基石,是解决“数据如何在机器中被表示与运算”的问题。冯·诺依曼体系结构中,一切信息(数值、字符、指令)最终都转化为二进制比特流。然而,二进制串本身是“无意义”的,其含义完全取决于解释规则。本章将系统梳理数值型数据的定点与浮点表示、机器数编码方案(原码/反码/补码)、字符编码标准以及数据校验机制,帮助读者建立从“物理比特”到“逻辑数值”的完整映射认知。
上图展示了本章知识体系的整体框架。数值数据(定点与浮点)关注“如何用有限位宽表达实数范围与精度”,机器数编码(原码/反码/补码)解决“如何让加减法统一为加法运算”,字符编码解决“非数值信息的二进制映射”,而校验码则保障数据在存储或传输过程中的完整性。四者相互独立又彼此关联,共同构成计算机运算单元的输入输出基础。
3.1 定点数表示与机器数编码
3.1.1 核心原理:定点数的格式与局限
定点数约定小数点位置固定不变。常见格式有两种:纯整数(小数点固定在最低位之后)和纯小数(小数点固定在符号位之后)。例如,8位定点整数可表示范围是 -128~127(补码)或 -127~127(原码/反码)。定点数的优势在于运算简单、硬件实现成本低,但动态范围小,无法同时满足大范围和高精度的需求。例如,用16位定点整数表示圆周率,只能取3,精度损失严重。
3.1.2 判断方法:原码、反码、补码的转换规则
对于正数,三种编码的符号位为0,数值位与真值相同。对于负数,转换规则如下:
- 原码:符号位为1,数值位为值二进制表示。
- 反码:符号位为1,数值位为原码数值位按位取反。
- 补码:符号位为1,数值位为反码数值位加1(即原码数值位取反加1)。
补码的核心优势在于:减法可以转化为加法,且0的表示唯一(+0和-0的补码均为00000000)。例如,计算 5 - 3 时,可转换为 5 + (-3) 的补码运算:00000101 + 11111101 = 1 00000010,丢弃最高位进位后得到 00000010,即2。
| 真值 | 原码(8位) | 反码(8位) | 补码(8位) |
|---|---|---|---|
| +7 | 00000111 | 00000111 | 00000111 |
| -7 | 10000111 | 11111000 | 11111001 |
| +0 | 00000000 | 00000000 | 00000000 |
| -0 | 10000000 | 11111111 | 00000000(唯一) |
3.1.3 案例拆解:补码运算的溢出判断
假设使用4位补码表示整数,计算 7 + 1。7的补码为0111,1的补码为0001,相加得1000。由于符号位从0变为1,且最高数值位产生进位而符号位无进位,发生溢出。判断溢出的常用规则是:最高位进位与次高位进位异或为1时溢出。此例中,次高位(bit2)进位为1,最高位(bit3)进位为0,异或结果为1,故溢出。实际结果为-8,显然错误。这说明定点数运算必须考虑位宽限制,否则结果不可信。
3.2 浮点数表示:IEEE 754标准
3.2.1 核心原理:科学计数法的二进制实现
IEEE 754标准定义了浮点数的存储格式,以32位单精度(float)为例,其布局为:1位符号位(S)、8位阶码(E)、23位尾数(M)。真值计算公式为:(-1)^S × 1.M × 2^(E-127)。其中,阶码采用偏置码表示,单精度偏置值为127,双精度为1023。尾数采用隐含位技术,即规格化数的小数点前一位恒为1,不显式存储,从而多获得1位精度。
3.2.2 判断方法:规格化与非规格化数的识别
- 规格化数:阶码E不全为0且不全为1,此时尾数隐含1,即1.M。
- 非规格化数:阶码E全为0,此时尾数隐含0,即0.M,用于表示接近0的极小数值。
- 特殊值:阶码全为1且尾数全为0表示无穷大(±∞);阶码全为1且尾数非0表示NaN(非数值)。
例如,将十进制数 -12.75 转换为单精度浮点数:符号位S=1;12.75的二进制为1100.11,规格化为1.10011 × 2^3;阶码E=3+127=130,即10000010;尾数M=10011000000000000000000。最终存储为:1 10000010 10011000000000000000000。
3.2.3 案例拆解:浮点数精度损失与比较陷阱
在C语言中执行 float a = 0.1f; float b = 0.2f; if (a + b == 0.3f) 通常为假。原因是0.1和0.2在二进制中均为无限循环小数,存储时被截断,导致累加结果与0.3的存储值存在微小差异。实际工程中,应使用误差容限比较:fabs(a + b - 0.3f) < 1e-6。此外,浮点数运算不满足结合律,例如 (1e20 + 1) - 1e20 的结果为0,而 1e20 + (1 - 1e20) 的结果为0,但 (1e20 - 1e20) + 1 的结果为1。这说明运算顺序会影响精度。
3.3 字符编码与校验码
3.3.1 核心原理:从ASCII到Unicode的演进
ASCII码使用7位二进制表示128个字符(含控制字符),扩展ASCII使用8位表示256个字符。但ASCII无法覆盖中文、日文等非拉丁文字。Unicode字符集为每个字符分配唯一的码点(如“中”的码点为U+4E2D),而UTF-8是Unicode的一种变长编码方案,用1~4个字节表示一个字符,兼容ASCII,且无字节序问题。例如,“A”的UTF-8编码为0x41,“中”的编码为0xE4 0xB8 0xAD。
3.3.2 判断方法:校验码的检错与纠错能力
校验码用于检测或纠正数据在传输/存储中的错误。常见方案包括:
- 奇偶校验:在数据位后附加1位,使整个码字中1的个数为奇数(奇校验)或偶数(偶校验)。只能检测奇数位错误,无法纠错。
- CRC(循环冗余校验):将数据视为多项式,除以生成多项式,余数作为校验码。可检测突发错误,广泛应用于网络通信(如以太网帧的FCS)。
- 海明码:在数据位之间插入多个校验位,不仅能检测错误,还能定位并纠正单比特错误。例如,8位数据需要4个校验位,形成12位码字。
| 校验方式 | 校验位数量 | 检错能力 | 纠错能力 | 典型应用 |
|---|---|---|---|---|
| 奇偶校验 | 1 | 奇数位错误 | 无 | UART串口 |
| CRC-32 | 32 | 突发错误(长度≤32) | 无 | 以太网、ZIP压缩 |
| 海明码 | log2(n)+1 | 多比特错误(部分) | 单比特错误 | ECC内存 |
3.3.3 案例拆解:海明码的编码与纠错过程
以4位数据D3D2D1D0=1011为例,需要3个校验位P2P1P0,码字排列为P2P1D3P0D2D1D0(位置1~7)。校验位覆盖规则:P0覆盖位置1,3,5,7;P1覆盖位置2,3,6,7;P2覆盖位置4,5,6,7。计算各校验位使对应组内1的个数为偶数:P0=D3⊕D2⊕D0=1⊕0⊕1=0;P1=D3⊕D1⊕D0=1⊕1⊕1=1;P2=D3⊕D2⊕D1=1⊕0⊕1=0。发送码字为0101011。若接收端收到0101111(位置6发生错误),则重新计算各组校验:组0(位置1,3,5,7)=0⊕1⊕1⊕1=1;组1(位置2,3,6,7)=1⊕1⊕1⊕1=0;组2(位置4,5,6,7)=1⊕1⊕1⊕1=0。将组号组合为二进制100(即4),表示位置4出错?实际错误位置为6,但计算得4,说明规则需按位置编号的二进制位来分组。正确做法:将出错位置编号的二进制位对应校验组,此处位置6的二进制为110,即组2和组1出错,组0正确,组合为110(十进制6),定位到位置6,取反即可纠正。