1. 从金融交易到科学计算:为什么我们需要浮点数?
记得我第一次接触银行系统开发时,发现所有金额都精确到分(0.01元)。当时系统采用定点数表示法——用32位整数的最后两位表示小数部分。这种方案简单直接,比如金额123.45元存储为12345,计算时只需记住"最后两位是分"这个约定。
但当我尝试用同样方法计算圆周率时,问题立刻显现。假设我们用64位整数,后30位表示小数部分,那么:
- 最大能表示的数字是2^34-1(约171亿)
- 最小精度是2^-30(约9.31×10^-10)
这看起来不错?但当计算π≈3.1415926535...时:
- 需要至少10位小数精度
- 计算过程中会出现像1/3=0.333...这样的无限循环小数
- 进行(√3-√2)≈0.317837245...这类运算时,精度损失会累积
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 科学计数法的二进制改造
2.1 从十进制到二进制的思维转换
科学计数法在十进制中表示为:±m×10^e,其中1≤m<10。将其移植到二进制:
- 基数从10变为2
- 尾数m满足1≤m<2(二进制下整数部分总是1)
- 例如:0.0001011(二进制) = 1.011×2^-4
2.2 浮点数的三要素
一个完整的浮点数表示需要:
- 符号位(Sign):1位,0正1负
- 指数部分(Exponent):移码表示(后面详解)
- 尾数部分(Mantissa):隐含前导1
以32位单精度浮点数为例:
code复制[31]符号位 [30-23]8位指数 [22-0]23位尾数
3. IEEE 754标准详解
3.1 为什么需要标准化?
早期计算机厂商各自为政:
- IBM用基数为16的浮点格式
- Cray用特殊格式提高向量运算速度
- 小型机厂商自定义格式
导致数值计算结果不一致,IEEE 754-1985应运而生。
3.2 单精度浮点数的内存布局
c复制struct IEEE754_float {
unsigned int mantissa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
};
实际值为:(-1)^sign × 1.mantissa × 2^(ex
