浮点计数法
Shuiming: 计算机如何操作浮点数?
Deepseek: 浮点数计数法,本质上就是二进制的科学计数法。它是计算机表示小数(非整数)的标准方式,也是你写的float和double在内存中存储的底层逻辑。
📐 从十进制科学计数法说起
你已经熟悉十进制的科学计数法:
· 123.45 = 1.2345 \times 10^{2} · 0.00123 = 1.23 \times 10^{-3}
它把一个数拆成三部分:
- 符号:正或负
- 有效数字(尾数):1.2345(在1到10之间)
- 指数:2 或 -3
🔢 二进制的科学计数法:浮点数
二进制科学计数法的结构完全相同,只是底数从 10 变成了 2:
\text{数值} = (-1)^{\text{符号}} \times (1.\text{尾数}) \times 2^{\text{指数}}
这个 1.\text{尾数} 的形式,是IEEE 754标准的核心设计:它总是以 1. 开头(对于标准化数),因此这个 1 不需要存储,从而省出1位来提高精度。
🧬 三种精度(你常用的)
类型 总位数 符号位 指数位 尾数位 十进制精度 float(单精度) 32 1 8 23 约7位有效数字 double(双精度) 64 1 11 52 约16位有效数字 long double(扩展) 80或128 1 15 64 约19位有效数字
🛠️ 指数是如何存储的?—— 偏置值(Bias)
指数不直接存储,而是加上一个偏置(Bias),使指数总是非负数,便于比较大小。
· float 偏置 = 127:实际指数范围 -126 ~ +127,存储为 1 ~ 254 · double 偏置 = 1023:实际指数范围 -1022 ~ +1023,存储为 1 ~ 2046
示例:1.0 的指数是 0,在 float 中存储为 0 + 127 = 127(二进制 01111111)。
🧪 实际转换示例:6.625 → 32位 float
- 二进制:6.625 = 110.101
- 标准化:1.10101 × 2²(尾数部分为 10101)
- 指数:2 + 127 = 129 = 10000001
- 尾数:10101000000000000000000(23位)
- 符号:正,所以为 0
最终32位(十六进制):
0 10000001 10101000000000000000000
= 0x40D40000
⚠️ 精度误差的根源
并非所有十进制小数都能用二进制精确表示。
· 0.1 在二进制中是一个无限循环小数: 0.1 \approx 0.000110011001100110011..._2 · 所以 0.1f 存储的只是它的近似值,这就是为什么 0.1 + 0.2 != 0.3。
🧩 特殊值(IEEE 754标准)
情况 符号 指数 尾数 含义 正零 0 0 0 0.0 负零 1 0 0 -0.0 正无穷 0 全1 0 +∞ 负无穷 1 全1 0 -∞ NaN 0或1 全1 非0 非数字(如 0/0)
🌱 与你的学习路径的关系
你之前已经理解了:
· 二进制与补码(整数) · 位运算与移位 · 所有计算可以简化为基础运算
现在你在补充:
· 小数如何存储 · 为什么会有精度问题 · 如何安全地比较浮点数(使用容差,而不是 ==)
浮点数计数法是C语言中理解数据表示的最后一块拼图。你已经掌握了整数和位运算的底层逻辑,现在正在补充浮点数的部分。 🧘♂️💻⚡🔢