CSAPP
Chapter 04:数据的机器级表示与处理
浮点数
使用 IEEE754 标准
在 32 位浮点数(float)中,这 32 个格子被切分成了三块:1位符号位 (S) + 8位阶码 (E) + 23位尾数 (M)。
在 64 位浮点数(double)中,这 64 个格子被切分成了三块:1位符号位 (S) + 11位阶码 (E) + 52位尾数 (M)。
- 定符号 (Sign)
- 正数:S = 0
- 负数:S = 1
- 转二进制 (Binary)
- 分别将整数部分和小数部分转化为二进制。
- 规格化 (Normalization)
- 移动小数点,直到变成 1.xxxx×2E 的形式。
- 关键点: 此时小数点左边必须是 1(因为二进制非零数首位只能是 1),这个 1 在存储时会被省略(隐含位)。
- 算阶码 (Exponent)
- 公式:阶码值 = 指数 E + 偏移量 127
- 算尾数 (Mantissa)
- 取规格化后小数点右边的部分。
- 如果不够 23 位,在后面补 0。
- 拼接
- 把 S、E、M 拼起来,最后每 4 位转成一位十六进制。
补码
计算机中几乎所有的有符号整数都使用补码存储,因为这样可以让加法和减法共用一套电路。
标准计算步骤:
- 求原码 (Absolute Value):先不管负号,算出这个数绝对值的二进制。
- 求反码 (Invert):按位取反,0 变 1,1 变 0。
- 求补码 (Add 1):末位加 1。
快速口诀: “补码 = 原码取反加一”。
大端与小端
数据从左到右是从高位到低位,字节是最小单元,数据的存储都以字节为单位。
计算出机器码对应的十六进制字节之后,再进行存储。
大端存储转换为小端存储只是调换字节的顺序,而不是将机器码逆序。
- 大端模式 (Big-Endian):数据的高位字节 (MSB) 存放在内存的低地址端。
- 小端模式 (Little-Endian):数据的低位字节 (LSB) 存放在内存的低地址端。
例题
将 float x = 179.0 和 int y = -179 转换为 32 位小端存储
浮点数
1. 十进制转二进制
- 整数部分 179:
- $ 179 = 128 + 32 + 16 + 2 + 1 $
- 二进制:
10110011
2. 规格化(Normalization)
- 将小数点移动到第一个
1的后面:- $ 101100112 = 1.0110011 × 2^7 $
- 这里得到:
- 指数 (Index) = 7
- 尾数 (Mantissa) =
0110011(去掉隐含的整数位 1)
3. 计算各部分的值
- 符号位 (S):正数 →
0 - 阶码 (E):指数 + 偏移量 (127)
- $ E = 7 + 127 = 134 $
- 134 转二进制 →
10000110
- 尾数 (M):补齐 23 位
0110011后面补 16 个 0 →01100110000000000000000
4. 拼接并转十六进制
- 二进制流:
01000011001100110000000000000000 - 按 4 位一组分组:
01000011001100110000000000000000 - 转十六进制:
43330000 - 最终机器数:
43 33 00 00(Hex)
补码
1. 求原码(绝对值的二进制)
- $| -179 | = 179$
- 二进制:
0000 0000 0000 0000 0000 0000 1011 0011 - 十六进制:
00 00 00 B3
2. 求反码(按位取反)
-
所有位
0变1,1变0:1111 1111 1111 1111 1111 1111 0100 1100 -
十六进制:
FF FF FF 4C
3. 求补码(末位 +1)
... 4C+1=... 4D- 最终机器数:
FF FF FF 4D(Hex)
存储
| 变量 | 地址 | 字节 (Hex) | 备注 |
|---|---|---|---|
| y | 31BH | FF | 最高位 (MSB) |
| 31AH | FF | ||
| 319H | FF | ||
| 318H | 4D | 最低位 (LSB) | |
| x | 317H | 43 | 最高位 (MSB) |
| 316H | 33 | ||
| 315H | 00 | ||
| 314H | 00 | 最低位 (LSB) |

Comments | NOTHING