浮点数精度与转化

不同浮点数类型之间的转换可能引入精度损失。

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)

字段位数
sign1
exp5
frac10
  • 精度:约3.3位十进制有效数字(
  • 范围:最大值为 65504(
  • 分级精度:最小规格化数

bf16(Brain Floating Point)

由Google为深度学习训练设计,是fp32的截断版本:

字段位数
sign1
exp8
frac7
  • 精度:约2.4位十进制有效数字(
  • 范围:与fp32完全相同(
  • 保持了fp32的指数范围,但尾数只有7位

对比总结

特性fp16bf16
有效精度11位(含隐含1)8位(含隐含1)
范围
适用场景通用计算深度学习训练/推理

bf16专为机器学习设计:模型训练中权重和梯度的范围很大(需要fp32的指数范围),但精度要求不高(可以接受较少的尾数位)。相比于fp16,bf16不需要loss scaling即可处理更广泛的数值范围,简化了训练流程。

相关笔记

链接到