小数在内存里到底长啥样?
1. 测试环境说明
以下数据基于 Visual Studio x86(32位) 环境实测。IEEE 754 是跨平台标准,float 和 double 的结构在所有平台上保持一致。
| 开发环境 | Visual Studio |
| 目标平台 | x86(32位) |
| 字节序 | 小端存储 |
2. 本文目标
上一篇我们把整数的家底翻了个遍——补码、大小端、类型转换。整数很老实,说一不二,存进去是多少,读出来就是多少。
但小数就没那么乖了。本文拆解 float 和 double 的 IEEE 754 存储结构,回答三个问题:
- float 和 double 到底差在哪?
- 为什么 0.1 + 0.2 不等于 0.3?
- 同一块内存,用 int 和 float 去读,为什么结果完全不一样?
3. 先看全貌:浮点数家族
在深入细节之前,先把两种浮点类型的“档案”摆出来,有个整体印象。
| float | %f | 4 | S(1) + E(8) + M(23) | 127 | 约 7 位 |
| double | %lf | 8 | S(1) + E(11) + M(52) | 1023 | 约 15 位 |
三个组成部分:
- S(Sign):符号位。0 正 1 负,最简单的一位。
- E(Exponent):指数位。存的是“真实指数 + 中间值”,后面会解释为什么这么绕。
- M(Mantissa):尾数位。只存小数点后面的部分,前面的 1 被省掉了——这是 IEEE 754 最精妙的设计之一。
先记住结论:double 比 float 多了 3 位指数 + 29 位尾数,所以它能表示更大范围的数,同时精度也更高。代价是多占 4 个字节。
光看表格可能抽象,接下来我们亲手转一个数,整个过程就清楚了。
4. 亲手转换一遍:12.25 是怎么存进内存的
把十进制小数变成 32 个比特,分三步走。
第一步:十进制转二进制
- 整数部分:12 → 1100
- 小数部分:
- 0.25 × 2 = 0.5 → 取 0
- 0.5 × 2 = 1.0 → 取 1
- 0.25 → 0.01
结果:12.25 → 1100.01
整数部分连除取余,小数部分连乘取整,套路是固定的。
第二步:写成二进制科学计数法
1100.01=(−1)0×1.10001×231100.01 = (-1)^0 \\times 1.10001 \\times 2^31100.01=(−1)0×1.10001×




![[C++]算法双指针 复写0-171主机测评](https://www.171host.com/wp-content/uploads/2026/09/20260910013601-6aa2098179e1b-220x150.png)
