为什么需要浮点数?
最主要的原因是按照整数这种定位数去在计算机中存储,存的数量没有满足到需求。譬如
寄存器只有4位的话,存储整数最多存储10000个,范围是0~9999。
1
0
4
=
10000
10^4 = 10000
104=10000
如果是小数呢,加入小数点固定在中间,如99.99,存储的数量也是10000。那么9.999怎么存储呢,向左移动一位就好了啊,是的,那么就用到科学计数法。
9999
×
1
0
−
3
=
9.999
9999 \times 10^{-3} = 9.999
9999×10−3=9.999
这种可以控制小数点变动的就叫做浮点数。
浮点数,是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。
用科学计数法的方式就可以满足存储的要求。
IEEE 754 定义
表达式如下:
( − 1 ) s × 1. f × 2 e (-1)^s \times 1.f \times 2^e (−1)s×1.f×2e
-
s=sign,e=exponent,f=fraction.
-
s表示符号位,当s=0,V为正数;当s=1,V为负数。
-
f表示有效数字,1.f整体大于等于1,小于2。
-
e表示指数位。
精度 | 符号位数 | 指数位数 | 有效位 |
---|---|---|---|
32位单精度 | 1 | 8 | 23 |
64位双精度 | 1 | 11 | 52 |
规约形式的浮点数
按照IEEE 754规定的,而且有效位小数点左边的数字为1的情况,就是规约形式的浮点数。
由于这种表示下的尾数有一位隐含的二进制有效数字,为了与二进制科学计数法的尾数(mantissa)相区别,IEEE754称之为有效数(significant)。
为什么叫有效位呢?因为按照约定,小数点左边的1是固定的,所以在存储器层面上不会存储这个位,同时为存储的位数增加了一位,按照32位来说,有效位就是23位(如果要存储小数点左边的1只有22位)。
指数偏移值
以32位为例子,指数位可以表示的范围大概如下,大概就是0~256
2
8
=
256
2^8 = 256
28=256
按照32位来看,那么负数怎么办?IEEE 754就想到个折中的办法,切割一般给负数吧。
-127~-1共127个负数,1~128共128个正数,还有0这个自然数,总共256个值。
最小值
(
−
1
)
−
1
×
1.00000000000000000000000
×
2
255
(-1)^{-1} \times 1.00000000000000000000000 \times 2^{255}
(−1)−1×1.00000000000000000000000×2255
最大值
(
−
1
)
0
×
1.00000000000000000000000
×
2
255
(-1)^0 \times 1.00000000000000000000000 \times 2^{255}
(−1)0×1.00000000000000000000000×2255
绝对值最小值
(
−
1
)
0
×
1.00000000000000000000000
×
2
0
(-1)^0 \times 1.00000000000000000000000 \times 2^{0}
(−1)0×1.00000000000000000000000×20
那么存储在计算机存储器怎么办?负数怎么表示,难道又要保存符号位?
为了提升效率,IEEE 754想到通过类似移位的方式就可以完成操作,因为这部分直接在电路就可以完成。而且还可以增加一位的存储空间,一举两得。
表示值 | 移位值 | 存储值 |
---|---|---|
-127 | 127 | 0 |
-126 | 127 | 1 |
-125 | 127 | 2 |
。 | 。 | 。 |
。 | 。 | 。 |
0 | 127 | 127 |
。 | 。 | 。 |
。 | 。 | 。 |
125 | 127 | 253 |
126 | 127 | 254 |
127 | 127 | 255 |
最小值
(
−
1
)
−
1
×
1.00000000000000000000000
×
2
−
126
(-1)^{-1} \times 1.00000000000000000000000 \times 2^{-126}
(−1)−1×1.00000000000000000000000×2−126
最大值
(
−
1
)
0
×
1.00000000000000000000000
×
2
127
(-1)^0 \times 1.00000000000000000000000 \times 2^{127}
(−1)0×1.00000000000000000000000×2127
绝对值最小值
(
−
1
)
0
×
1.00000000000000000000000
×
2
−
126
(-1)^0 \times 1.00000000000000000000000 \times 2^{-126}
(−1)0×1.00000000000000000000000×2−126
非规约形式的浮点数
如果浮点数的指数部分(e)的编码值是0,分数部分非零,那么这个浮点数将被称为非规约形式的浮点数。非规约形式按照如下表示(这部分的转换在电路层面应该完成了):
在 e 为 0 且 f 为 不全为0 的时候,就按照以下公式
(
−
1
)
s
×
0.
f
×
2
e
(-1)^s \times 0.f \times 2^e
(−1)s×0.f×2e
浮点数的特殊情况(0,溢值)
这个时候你会想,0(-126)和255(128)到哪里去了?他们用于0和溢值上面了。
在 e 为 255 且 f 为 0 的时候,我们就把这个浮点数认为是 无穷大。
还有就是超过了范围的,因为32位是有限的,上下限超过了,自然就没办法用浮点数来表示了,这种情况就是无穷值。
在 e 为 255 且 f 为 非0 的时候,我们就把这个浮点数认为是 NAN。
最后就是NAN值,有些算数表示式没办法表示的,如负数开平方。
总结以下:
指数位 (e) | 有效位(f) | 符号(s) | 表示 |
---|---|---|---|
0 | 0 | 0或1 | 0 |
0 | 非0 | 0或1 | 非规约0.f |
255 | 0 | 0 | 正无穷 |
255 | 0 | 1 | 负无穷 |
255 | 非0 | 0或1 | NAN |