IEEE 浮点数标准中定义用V = (-1)^s * M * 2 ^ E
来表示一个浮点数:
- s : 符号,1位符号位s直接编码符号 s
- M : 尾数,n位小数字段
frac = f[n-1]f[kn-1]f[n-3]...f[0]
编码尾数 M - E : 阶码,k位阶码字段
exp = e[k-1]e[k-1]e[k-3]...e[0]
编码阶码 E
单精度(32位表示)中 s exp frac 分布分别如下:
31 30... 23 22 .... 0
┌──────────────────────────────────────────┐
│s│ exp │ frac │
└──────────────────────────────────────────┘
其中s,exp,frac位数分别位 1,8,23,而双精度(64位表示)中s,exp,frac位数分别位 1,11,52
Bias : 2 ^ (k-1) -1 (单精度 127,双精度 1023)
E = exp - Bias,因此 E 取值范围: -126 ~ 127 (单精度) 或者 -1022 ~ 1023 (双精度)
M = 1.frac
E = 1 - Bias, E = -126 (单精度) 或者 E = -1022(双精度) : 1 - Bias 可以使非规格化到规格化部分平滑过渡
M = 0.frac
非规格化数 用来表示
- 0 : +0.0 -0.0
- 非常接近于0的数
frac 为 0 : 表示 正负无穷 frac 不为 0 : 表示 NaN
- 用8位数据表示一个浮点数,k=4,n=3,则会得到如下图的示例
从图中可以看到,最大非规格化数到最小规格化数之间的平滑过渡,这是由于:
最大非规格化数 : E = 1 - Bias , M = 0.111
最小规格化数 : E = 1 - Bias , M = 1
最小规格化数与所有非规格化数的E实际都是一样的,因此分布平滑.
- 用6位数据表示一个浮点数,k=3,n=2,则可以表示的值在坐标轴上分布情况如下
可以看到非规格化数分布式非常均匀的,而规格化数越靠近0分布越密集.
以单精度为例:(s,exp,frac位数分别位 1,8,23)
- 0.1 用二进制表示为 0.0 0011 0011 0011 0011 … (循环0011)
- 移位 4 得到(保留小数点后 23 位) : 1.1 0011 0011 0011 0011 0011 00
- 最后一位补 1 , M = 1.1 0011 0011 0011 0011 0011 01 , frac = 1 0011 0011 0011 0011 0011 01
- 0.1 = M >> 4 = M * 2 ^ -4 , 因此 阶码 E = - 4 , 即 exp = 01111011
0.1 存储为 0 01111011 10011001100110011001101 由于尾数精度问题 实际值为 : 0.000110011001100110011001101, 转换成10进制 : 0.10000000149011612.
- 0.2 用二进制表示为 0. 0011 0011 0011 0011 … (循环0011)
- 移位 3 得到(小数点后 23 位) : 1.10011001100110011001100
- 最后一位补 1 , M = 1.1 0011 0011 0011 0011 0011 01 , frac = 10011001100110011001101
- 0.2 = M >> 3 = M * 2 ^ -3 , 因此 阶码 E = - 3 , 即 exp = 01111100
0.2 存储为 0 01111100 10011001100110011001101 由于尾数精度问题 实际值为 : 0.00110011001100110011001101, 转换成10进制 : 0.20000000298023224.
0.000110011001100110011001101
+ 0.00110011001100110011001101
-----------------------------------
= 0.010011001100110011001100111
Round
= 0.010011001100110011001101
= 0.30000001192092896 (十进制)