科学计数法
复习一下科学计数法的定义:把一个数表示成 a a a 与 10 10 10 的 n n n 次幂相乘的形式( 1 ≤ ∣ a ∣ < 10 1≤|a|<10 1≤∣a∣<10, n n n为整数),即 a ∗ 1 0 n a * 10^n a∗10n,其中 a 称为有效数字。可以看到,如果要存储用科学计数法表示的数,需要存储 a a a 和 n n n 的值,其中 a a a 可能是正数,也可能是负数。如果我们需要用 16 个bit 来存储,则有了 FP16 数据格式
FP16
FP 表示 Float-Point,16 表示使用 16 个 bit。每个 bit 的含义如下所示:

其中 sign 表示符号位,0 表示正数,1表示负数。exponent 表示指数,对应上面的 n n n,fraction 表示有效数字的小数部分,整数部分为 0 0 0 或者 1 1 1(取 0 还是 取1 取决于 exponent 的值),对应上面的 a a a。这里有一些区别,一般的科学计数法是 10 的 n n n 次幂,在这里则是 2 的 n n n 次幂。
exponent 的取值范围
exponent 中的值是采用 offset-binay 的格式表示的。也就是 真实值 = 机器码 - offset,这里的 offset 是 15 = 01111,所以如果 exponent 的值为 11011,则其真实值 = 1101 1 2 − 0111 1 2 = 110 0 2 = 1 2 10 = 11011_2 - 01111_2 = 1100_2 = 12_{10} =110112−011112=11002=1210。所以理论上 exponent 的取值范围为 [ 00000 − 01111 [00000 - 01111 [00000−01111, 11111 − 01111 ] 11111 - 01111] 11111−01111] ,即 [ − 15 , 16 ] [-15,16] [−15,16]。但是由于 00000 00000 00000 和 11111 11111 11111 有其他的用途( 00000 00000 00000 用于限制有效数字的小数部分为 0, 11111 11111 11111 用于表示无穷大或异常值),所以实际取值范围为 [ − 14 , 15 ] [-14, 15] [−14,15]
最终形式
所以对于一个给定的 FP16 浮点数,假设 sign 的取值为
s
s
s,exponent 的取值为
e
e
e,fraction 的取值为
f
f
f,则
其表示的真实离散值的计算方法如下:
exponent | value |
---|---|
00000 | ( − 1 ) s ∗ 2 − 14 ∗ ( 0 + f 1024 ) (-1)^s * 2^{-14}*(0 + \frac{f}{1024}) (−1)s∗2−14∗(0+1024f) |
[ 00001 , 11110 ] [00001, 11110] [00001,11110] | ( − 1 ) s ∗ 2 e − 15 ∗ ( 1 + f 1024 ) (-1)^s * 2^{e-15}*(1 + \frac{f}{1024}) (−1)s∗2e−15∗(1+1024f) |
11111 | ± ∞ \pm \infty ±∞,或 NaN(当 fraction 不为 0 时,表示非法值) |
从上面可以看出,exponent 决定了计算方式。当 exponent 取值为 00000 时,指数取最小值 -14,有效数字的整数部分取 0,fraction 的取值范围 f ∈ [ 0 1024 , 1023 1024 ] f \in [\frac{0}{1024},\frac{1023}{1024}] f∈[10240,10241023],有效数字 ∈ [ 0 + 0 1024 , 0 + 1023 1024 ] \in [0 + \frac{0}{1024}, 0+\frac{1023}{1024}] ∈[0+10240,0+10241023]。
当 exponent 的取值为 11111 时,当且仅当 fraction 为 0 时,表示 ± ∞ \pm \infty ±∞,其他情况表示无效值。
当 exponent ∈ [ 00001 , 11110 ] \in [00001, 11110] ∈[00001,11110]时,exponent - 15 ∈ [ − 14 , 15 ] \in [-14, 15] ∈[−14,15],有效数字的整数部分取 1,fraction 的取值范围 f ∈ [ 0 1024 , 1023 1024 ] f \in [\frac{0}{1024},\frac{1023}{1024}] f∈[10240,10241023],有效数字 ∈ [ 1 + 0 1024 , 1 + 1023 1024 ] \in [1 + \frac{0}{1024}, 1+\frac{1023}{1024}] ∈[1+10240,1+10241023]。
几个特殊值
Binary | Hex | Value | Notes |
---|---|---|---|
0 00000 0000000000 | 0000 | 0 | |
0 00000 0000000001 | 0001 | 2 − 14 × ( 0 + 1 1024 ) ≈ 0.000000059604645 2^{−14} × (0 + \frac{1}{1024}) \approx 0.000000059604645 2−14×(0+10241)≈0.000000059604645 | 最小正 subnormal 数 |
0 00000 1111111111 | 03ff | 2 − 14 × ( 0 + 1023 1024 ) ≈ 0.000060975552 2^{−14} × (0 + \frac{1023}{1024})\approx0.000060975552 2−14×(0+10241023)≈0.000060975552 | 最大正 subnormal 数 |
0 00001 0000000000 | 0400 | 2 − 14 × ( 1 + 0 1024 ) ≈ 0.00006103515625 2^{−14} × (1 + \frac{0}{1024})\approx0.00006103515625 2−14×(1+10240)≈0.00006103515625 | 最小正 normal 数 |
0 01101 0101010101 | 3555 | 2 − 2 × ( 1 + 341 1024 ) ≈ 0.33325195 2^{−2} × (1 + \frac{341}{1024})\approx0.33325195 2−2×(1+1024341)≈0.33325195 | 接近1/3 |
0 01110 1111111111 | 3bff | 2 − 1 × ( 1 + 1023 1024 ) ≈ 0.99951172 2^{−1} × (1 + \frac{1023}{1024}) ≈ 0.99951172 2−1×(1+10241023)≈0.99951172 | 最大的小于 1 的数 |
0 01111 0000000000 | 3c00 | 2 0 × ( 1 + 0 1024 ) = 1 2^0 × (1 + \frac{0}{1024} ) = 1 20×(1+10240)=1 | 1 |
0 01111 0000000001 | 3c01 | 2 0 × ( 1 + 1 1024 ) ≈ 1.00097656 2^0 × (1 + \frac{1}{1024}) ≈ 1.00097656 20×(1+10241)≈1.00097656 | 最小的大于1的数 |
0 11110 1111111111 | 7bff | 2 15 × ( 1 + 1023 1024 ) = 65504 2^{15} × (1 + \frac{1023}{1024 }) = 65504 215×(1+10241023)=65504 | 最大 normal 数 |
0 11111 0000000000 | 7c00 | ∞ \infty ∞ | 无穷大 |
1 00000 0000000000 | 8000 | −0 | |
1 10000 0000000000 | c000 | − 2 = − 1 × 2 1 -2 = -1\times2^1 −2=−1×21 | |
1 11111 0000000000 | fc00 | − ∞ -\infty −∞ | 负无穷大 |
可以表示的离散值个数
当 exponent 为 00000 时,fraction 的取值为
[
0
,
1023
]
[0,1023]
[0,1023],再算上符号,共有
1024
∗
2
−
1
=
2047
1024 * 2 - 1 = 2047
1024∗2−1=2047 个值。
当 exponent 为 11111 时,只能表示
2
2
2 个值:
±
∞
\pm\infty
±∞
当 exponent
∈
[
1
,
30
]
\in [1, 30]
∈[1,30] 时,fraction
∈
[
0
,
1023
]
\in [0, 1023]
∈[0,1023],符号位可取正或负,所以可以取的值个数为:
30
∗
1024
∗
2
=
61440
30 * 1024 * 2 = 61440
30∗1024∗2=61440
所以总共可以表示 2047 + 2 + 61440 = 63489 2047 + 2 + 61440 = 63489 2047+2+61440=63489个值。
取值范围: [ ± 5.96 × 1 0 − 8 , 6.5504 × 1 0 4 ] [\pm 5.96 \times 10^{-8}, 6.5504 \times 10^4] [±5.96×10−8,6.5504×104]。横跨 12 个数量级。