浮点数精度与转化
不同浮点数类型之间的转换可能引入精度损失。
int → float 的转换
- 对于32位 int → float(fp32),float 的尾数只有位有效精度
- 超过24位有效数字的 int 值无法精确表示,需要舍入
- 例如
int x = 16777217;()转换为 float 时会舍入到最近的偶数
- 例如
- int 值范围 远大于 float 可精确表示的整数范围
- 但 float 的指数范围更大,可以表示绝对值更大的数(只是不精确)
float → int 的转换
- 直接截断小数部分(向零舍入)
- 如果 float 的值超出了 int 的表示范围,结果是未定义的(undefined behavior)
- 在许多系统上会得到
TMin(即 )或其它异常值
- 在许多系统上会得到
- 浮点数到整数的转换是程序中常见的bug来源
float → double → float
- float → double:绝对安全,double 的指数范围和精度都大于 float,数值精确保持
- double → float:可能损失精度(double 的 52+1 位尾数截断到 float 的 23+1 位),可能溢出到无穷大
fp16 与 bf16 的精度对比
在深度学习领域,两种16位浮点格式被广泛使用:
fp16(IEEE 754 half-precision)
| 字段 | 位数 |
|---|---|
| sign | 1 |
| exp | 5 |
| frac | 10 |
- 精度:约3.3位十进制有效数字()
- 范围:最大值为 65504()
- 分级精度:最小规格化数
bf16(Brain Floating Point)
由Google为深度学习训练设计,是fp32的截断版本:
| 字段 | 位数 |
|---|---|
| sign | 1 |
| exp | 8 |
| frac | 7 |
- 精度:约2.4位十进制有效数字()
- 范围:与fp32完全相同()
- 保持了fp32的指数范围,但尾数只有7位
对比总结
| 特性 | fp16 | bf16 |
|---|---|---|
| 有效精度 | 11位(含隐含1) | 8位(含隐含1) |
| 范围 | ||
| 适用场景 | 通用计算 | 深度学习训练/推理 |
bf16专为机器学习设计:模型训练中权重和梯度的范围很大(需要fp32的指数范围),但精度要求不高(可以接受较少的尾数位)。相比于fp16,bf16不需要loss scaling即可处理更广泛的数值范围,简化了训练流程。
相关笔记
链接到
- 上一个知识点:2.11 浮点数的分类与舍入
- 下一个知识点:无(本章最后一个知识点)