彻底搞懂float16与float32的计算方式

1 float 16与float 32

1.1 float16

1.1.1 计算方式

float 16又称半精度, 用16个比特也就是2个字节表示一个数。
如下图所示, 其中1位符号位, 5位指数位, 10位小数位。

彻底搞懂float16与float32的计算方式
那么, 这16个比特位是怎么表示1个数的呢 ? 分3部分:符号位 , 指数部分, 小数部分。

a 符号位: 1代表负数, 0代表正数。

b 指数部分,5个比特位, 全0和全1有特殊用途,所以是00001~11110, 也就是1到30, 减去偏置15,指数部分最终范围为-14 ~15.

c 小数部分, 10个比特位, 范围为(0~1023)/1024.

所以最终一个数据的计算方式为:

( − 1 ) s i g n ∗ 2 e x p o n e n t − 15 ∗ ( 1 + f r a c t i o n 1024 ) (-1)^{sign}2^{exponent-15}(1+\frac{fraction}{1024})(−1 )s i g n ∗2 e x p o n e n t −1 5 ∗(1 +1 0 2 4 f r a c t i o n ​)

但是需要注意, 有2个特殊情况, 也就是上面说的指数位全0和全1的特殊用途。
1)exponent全0
计算公式为
( − 1 ) s i g n ∗ 2 − 14 ∗ ( 0 + f r a c t i o n 1024 ) (-1)^{sign}2^{-14}(0+\frac{fraction}{1024})(−1 )s i g n ∗2 −1 4 ∗(0 +1 0 2 4 f r a c t i o n ​)

2)exponent全1
如果fraction全0 , 则表示+ i n f +inf +i n f或者− i n f -inf −i n f
如果fraction不全为0 , 则表示N a N NaN N a N

; 1.1.2 表示范围与精度

根据上面的计算方法,
fp16 的最大值为: 0 11110 1111111111 = 2 15 ∗ ( 1 + 1023 / 1024 ) = 65504 0 \quad11110 \quad 1111111111=2^{15}(1+1023/1024)=65504 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 =2 1 5 ∗(1 +1 0 2 3 /1 0 2 4 )=6 5 5 0 4
fp16 的最小值为: 1 11110 1111111111 = − 1 ∗ 2 15 ∗ ( 1 + 1023 / 1024 ) = − 65504 1 \quad11110 \quad 111111111 1=-1
2^{15}*(1+1023/1024)=-65504 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 =−1 ∗2 1 5 ∗(1 +1 0 2 3 /1 0 2 4 )=−6 5 5 0 4
精度为: 2 − 24 = 5.960464477539063 e − 08 2^{-24}=5.960464477539063e-08 2 −2 4 =5 .9 6 0 4 6 4 4 7 7 5 3 9 0 6 3 e −0 8

有效动态范围: 5.960464477539063e-08 ~65504 \quad 注意这里不是从最小值到最大值, 而是说的正数的部分, 因为正负是对称的

另外, 需要注意的一点是, fp16表示的数的范围是非均匀的, 什么意思呢? fp16表示的数的范围是-65536 – 65536, 但这些数并不是等间隔分布的。 在不同的区间, 间隔是不一样的, 最小的间隔为2 − 24 2^{-24}2 −2 4, 最大的间隔为2 5 2^5 2 5.

1.2 float32

1.2.1 计算方式

float32 又称单精度, 用32个比特数也就是4个字节表示一个数。
如下图所示, 其中1位符号位, 8位指数位, 23位小数位。

彻底搞懂float16与float32的计算方式
那么, 这32个比特位是怎么表示1个数的呢 ? 分3部分:符号位 , 指数部分, 小数部分。

a 符号位: 1代表负数, 0代表正数。

b 指数部分,8个比特位, 全0和全1有特殊用途,所以是00000001~11111110, 也就是1到254, 减去偏置127,指数部分最终范围为-126 ~127.

c 小数部分, 23个比特位, 范围为( 0 − − 2 23 − 1 ) / 2 23 (0 — 2^{23}-1)/2^{23}(0 −−2 2 3 −1 )/2 2 3

所以最终一个数据的计算方式为:

( − 1 ) s i g n ∗ 2 e x p o n e n t − 127 ∗ ( 1 + f r a c t i o n 2 23 ) (-1)^{sign}2^{exponent-127}(1+\frac{fraction}{2^{23}})(−1 )s i g n ∗2 e x p o n e n t −1 2 7 ∗(1 +2 2 3 f r a c t i o n ​)

但是需要注意, 有2个特殊情况, 也就是上面说的指数位全0和全1的特殊用途。
1)exponent全0
计算公式为
( − 1 ) s i g n ∗ 2 − 126 ∗ ( 0 + f r a c t i o n 2 23 ) (-1)^{sign}2^{-126}(0+\frac{fraction}{2^{23}})(−1 )s i g n ∗2 −1 2 6 ∗(0 +2 2 3 f r a c t i o n ​)

2)exponent全1
如果fraction全0 , 则表示+ i n f +inf +i n f或者− i n f -inf −i n f
如果fraction不全为0 , 则表示N a N NaN N a N

; 1.2.2 表示范围与精度

根据上面的计算方法,
fp32 的最大值为: 0 11111110 111111…..1111 = 2 127 ∗ ( 1 + 2 23 − 1 2 23 ) = 3.4028234663852886 e + 38 0 \quad11111110 \quad 111111…..1111=2^{127}(1+\frac{2^{23}-1}{2^{23}})=3.4028234663852886e+38 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 …..1 1 1 1 =2 1 2 7 ∗(1 +2 2 3 2 2 3 −1 ​)=3 .4 0 2 8 2 3 4 6 6 3 8 5 2 8 8 6 e +3 8
fp32 的最小值为: 1 11111110 111111…..1111 = − 1 ∗ 2 127 ∗ ( 1 + 2 23 − 1 2 23 ) = − 3.4028234663852886 e + 38 1 \quad11111110 \quad 111111…..1111=-1
2^{127}*(1+\frac{2^{23}-1}{2^{23}})=-3.4028234663852886e+38 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 …..1 1 1 1 =−1 ∗2 1 2 7 ∗(1 +2 2 3 2 2 3 −1 ​)=−3 .4 0 2 8 2 3 4 6 6 3 8 5 2 8 8 6 e +3 8
精度为: 2 − 149 = 1.401298464324817 e − 45 2^{-149}=1.401298464324817e-45 2 −1 4 9 =1 .4 0 1 2 9 8 4 6 4 3 2 4 8 1 7 e −4 5

有效动态范围:1.401298464324817e-45~3.4028234663852886e+38 \quad 注意这里不是从最小值到最大值, 而是说的正数的部分, 因为正负是对称的
同样地, fp32表示的数的范围是非均匀的. fp32表示的数的范围是-3.4028234663852886e+38 – 3.4028234663852886e+38, 但这些数并不是等间隔分布的。 在不同的区间, 间隔是不一样的, 最小的间隔为2 − 149 2^{-149}2 −1 4 9, 最大的间隔为2 104 2^{104}2 1 0 4.

Original: https://blog.csdn.net/leo0308/article/details/117398166
Author: leo0308
Title: 彻底搞懂float16与float32的计算方式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/617872/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球