Skip to content

Latest commit

 

History

History
100 lines (62 loc) · 3.35 KB

2.4.md

File metadata and controls

100 lines (62 loc) · 3.35 KB

浮点数

基本结构

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)

规格化 : exp 不全为 0 也不全为1

E = exp - Bias,因此 E 取值范围: -126 ~ 127 (单精度) 或者 -1022 ~ 1023 (双精度)

M = 1.frac

非规格化 : exp 全为 0

E = 1 - Bias, E = -126 (单精度) 或者 E = -1022(双精度) : 1 - Bias 可以使非规格化到规格化部分平滑过渡

M = 0.frac

非规格化数 用来表示

  • 0 : +0.0 -0.0
  • 非常接近于0的数

特殊值 : exp 全为 1

frac 为 0 : 表示 正负无穷 frac 不为 0 : 表示 NaN

示例

  • 用8位数据表示一个浮点数,k=4,n=3,则会得到如下图的示例

8位表示的浮点数非负值部分示例

从图中可以看到,最大非规格化数到最小规格化数之间的平滑过渡,这是由于:

最大非规格化数 : E = 1 - Bias , M = 0.111

最小规格化数 : E = 1 - Bias , M = 1

最小规格化数与所有非规格化数的E实际都是一样的,因此分布平滑.

  • 用6位数据表示一个浮点数,k=3,n=2,则可以表示的值在坐标轴上分布情况如下

6位表示的浮点数分布情况

可以看到非规格化数分布式非常均匀的,而规格化数越靠近0分布越密集.

十进制->float编码

以单精度为例:(s,exp,frac位数分别位 1,8,23)

0.1

  • 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.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.1 + 0.2

  0.000110011001100110011001101
+ 0.00110011001100110011001101
-----------------------------------
= 0.010011001100110011001100111
Round
= 0.010011001100110011001101
= 0.30000001192092896 (十进制)