第3章 数据的表示与运算
计算机系统的核心任务是对数据进行存储与运算,而数据在机器内部必须以二进制形式表示。理解进制转换、码制(原码/反码/补码)、定点数与浮点数格式以及算术逻辑运算的硬件实现原理,是分析计算机体系结构、编译原理乃至嵌入式系统底层行为的基础。本章将围绕“数据如何编码”与“运算如何执行”两条主线,系统梳理国网考试中高频出现的核心知识点,并结合典型例题与常见误区进行深度拆解。
3.1 进制转换:从原理到快速技巧
3.1.1 核心原理
进制转换的本质是位置计数法的等价变换。任意R进制数可表示为:
N = Σ(Ki × R^i) (i = m, m-1, ..., 1, 0, -1, -2, ...)
其中Ki为第i位上的数码(0 ≤ Ki ≤ R-1),R为基数,i为位权指数。计算机内部采用二进制(R=2),但为了书写与阅读方便,工程中常使用八进制(R=8)和十六进制(R=16)作为二进制的缩写形式。
3.1.2 转换方法与操作流程
| 转换方向 | 方法 | 示例 |
|---|---|---|
| R进制 → 十进制 | 按权展开求和 | (101.1)₂ = 1×4 + 0×2 + 1×1 + 1×0.5 = 5.5 |
| 十进制 → 二进制(整数) | 除2取余,逆序排列 | 13 → 1101 |
| 十进制 → 二进制(小数) | 乘2取整,顺序排列 | 0.625 → 0.101 |
| 二进制 ↔ 八进制 | 三位一组,不足补0 | (1101.01)₂ → (15.2)₈ |
| 二进制 ↔ 十六进制 | 四位一组,不足补0 | (1101.01)₂ → (D.4)₁₆ |
3.1.3 案例拆解:小数转换的精度问题
将十进制小数0.3转换为二进制:
0.3 × 2 = 0.6 → 取整数0
0.6 × 2 = 1.2 → 取整数1
0.2 × 2 = 0.4 → 取整数0
0.4 × 2 = 0.8 → 取整数0
0.8 × 2 = 1.6 → 取整数1
0.6 × 2 = 1.2 → 取整数1(开始循环)
结果:0.0100110011...₂(无限循环)
这说明十进制有限小数在二进制中可能成为无限循环小数。计算机浮点数只能保存有限位尾数,因此会产生舍入误差。在国网考试中,常以“0.1 + 0.2 ≠ 0.3”作为考点,其根源正是二进制无法精确表示0.1和0.2。
3.2 原码、反码与补码:机器数的编码逻辑
3.2.1 核心原理
机器数将符号位数字化:最高位为符号位(0正1负),其余位为数值位。三种码制的定义如下:
- 原码:符号位 + 值。例如8位原码中,+5 = 00000101,-5 = 10000101。
- 反码:正数与原码相同;负数符号位不变,数值位按位取反。例如-5的反码为11111010。
- 补码:正数与原码相同;负数在反码基础上末位加1。例如-5的补码为11111011。
补码的核心优势在于:将减法统一为加法运算,且0的表示唯一(00000000),无需单独设计减法器。
3.2.2 判断方法与转换流程
| 数值(8位) | 原码 | 反码 | 补码 |
|---|---|---|---|
| +7 | 00000111 | 00000111 | 00000111 |
| -7 | 10000111 | 11111000 | 11111001 |
| +0 | 00000000 | 00000000 | 00000000 |
| -0 | 10000000 | 11111111 | (不存在) |
| -128 | (无法表示) | (无法表示) | 10000000 |
3.2.3 实战场景:补码加减法运算
计算 5 - 3(8位补码):
5的补码:00000101
-3的补码:11111101
相加: 00000101 + 11111101 = 100000010
丢弃最高位进位,结果为 00000010 = +2 ✓
计算 -5 - 3:
-5的补码:11111011
-3的补码:11111101
相加: 11111011 + 11111101 = 111111000
丢弃进位,结果为 11111000 = -8 ✓
补码运算中,符号位参与运算,最终结果的符号位由运算自然产生,无需额外判断。
3.3 定点数与浮点数:数值范围的权衡
3.3.1 核心原理
定点数的小数点位置固定不变,通常分为定点整数(纯整数)和定点小数(纯小数)。定点数运算简单、速度快,但表示范围有限。例如8位定点整数范围为[-128, 127]。
浮点数采用科学计数法表示:N = M × R^E,其中M为尾数(通常为纯小数),R为基数(计算机中为2),E为阶码(指数)。浮点数通过调整阶码来扩大表示范围,但精度受尾数位数限制。
3.3.2 IEEE 754标准格式
| 类型 | 总位数 | 符号位 | 阶码位 | 尾数位 | 偏置值 | 范围(约) |
|---|---|---|---|---|---|---|
| 单精度float | 32 | 1 | 8 | 23 | 127 | ±3.4×10³⁸ |
| 双精度double | 64 | 1 | 11 | 52 | 1023 | ±1.8×10³⁰⁸ |
IEEE 754中,阶码采用移码(偏置码)表示,即实际存储值 = 真值 + 偏置值。尾数采用隐藏位技术:规格化浮点数的尾数最高位恒为1,因此不显式存储,从而多出1位有效精度。
3.3.3 案例拆解:浮点数表示与精度损失
将十进制数 -12.5 转换为IEEE 754单精度格式:
1. 符号位:负数 → 1
2. 整数部分:12 = 1100₂
3. 小数部分:0.5 = 0.1₂
4. 合并:12.5 = 1100.1₂ = 1.1001₂ × 2³
5. 阶码真值 = 3,存储值 = 3 + 127 = 130 = 10000010₂
6. 尾数(隐藏1后):10010000000000000000000
最终:1 10000010 10010000000000000000000
若尝试表示0.1,由于二进制无限循环,尾数只能截断为23位,产生约1.19×10⁻⁷的相对误差。在累加运算中,这种误差会不断累积。
3.4 算术逻辑运算与溢出判断
3.4.1 核心原理
算术逻辑单元(ALU)是CPU中执行算术运算(加减乘除)和逻辑运算(与或非异或)的组合逻辑电路。加法器是ALU的核心部件,通过全加器级联构成多位加法器。减法运算通过“减数取补码再加”实现。
3.4.2 溢出判断方法
溢出是指运算结果超出机器数所能表示的范围。判断溢出的三种常用方法:
| 方法 | 原理 | 示例(4位补码) |
|---|---|---|
| 双符号位法 | 运算前将符号位复制为两位,结果两位符号位不同则溢出 | 0111+0001=1000(符号位01,溢出) |
| 进位异或法 | 最高位进位与次高位进位异或,结果为1则溢出 | 0111+0001:次高位进位0,最高位进位1,异或=1,溢出 |
| 符号位判断法 | 两正数相加得负数,或两负数相加得正数,则溢出 | 7+1=8,但4位补码最大为7,结果-8,溢出 |
3.4.3 实战场景:溢出检测的硬件实现
在硬件设计中,溢出标志(Overflow Flag)通常由最高位进位与次高位进位的异或门产生。设C_out为最高位进位,C_{n-1}为次高位进位,则:
V = C_out ⊕ C_{n-1}
当V=1时表示有符号数运算溢出。注意:无符号数运算的溢出判断使用进位标志C_out,而非V标志。例如4位无符号数15+1=16,结果为0000且C_out=1,表示溢出;但若按有符号数解释,1111+0001=0000,V=0,表示-1+1=0,无溢出。
3.4.4 综合案例:补码运算的完整验证
设8位补码,计算 120 + 50:
120的补码:01111000
50的补码: 00110010
相加: 10101010 = -86(十进制)
实际结果应为170,但8位补码最大为127,因此溢出。
验证:次高位进位C6=0,最高位进位C7=1,V=1,溢出成立。
该案例说明,即使硬件执行了加法,若溢出标志置位,软件层必须进行异常处理或使用更高精度类型重新计算。
3.5 本章总结与复习要点
| 知识点 | 核心要点 | 易错点 |
|---|---|---|
| 进制转换 | 按权展开、除R取余、乘R取整 | 小数转换方向、分组补0位置 |
| 补码 | 负数补码=反码+1,0唯一 | 正数补码与原码相同,不要取反 |
| 浮点数 | IEEE 754格式、偏置值、隐藏位 | 阶码用移码而非补码 |
| 溢出判断 | 双符号位、进位异或 | 有符号与无符号溢出标志不同 |