一、计算机如何处理小数?
- 直观的想法是采用BCD码来表示一个小数,例如1.23可用0001.0010 0011来表示,但每一位需要用4为bit来表示,需要占用很多的位数,从信息量的角度来说,如果采用32位bit,可以表示40多亿个不同的数,而用BCD编码则只能表示1亿个数;
- 对于数值很大或很小的数,需要消耗非常多的位数;
鉴于上述缺点,目前计算机选择采用科学计数法的方式,通过有限的有效数位、底数和指数,来描述很大范围的数值;由于在科学计数法中小数点的位置是可以移动的,所以也称之为浮点数。
二、浮点数的编码规则
目前计算机的浮点数标准都遵循IEEE 754标准;
三、IEEE 754标准
-
IEEE 754标准用 V = ( − 1 ) s × M × 2 E V=(-1)^{s}\times M\times2^E V=(−1)s×M×2E的形式来表示一个数;
-
IEEE 754标准规定的两个基本格式分别为单精度32位bit(float) 和 双精度64位bit(double),格式如下。在此基础上还有扩展的格式,不过都大同小异。
- float格式
符号(s) | 阶码(e) | 尾数(f) |
---|---|---|
1bit | 8bits | 23bits |
- double
符号(s) | 阶码(e) | 尾数(f) |
---|---|---|
1bit | 11bits | 52bits |
-
符号位(s):0正1负;
-
阶码(e):指数部分,采用移码表示;对于规格数(整数部分非0),实际的值为 E = e − B i a s E=e-Bias E=e−Bias;对于非规格数,实际的值为 E = 1 − B i a s E=1-Bias E=1−Bias;其中 B i a s = 2 ( k − 1 ) − 1 Bias=2^{(k-1)}-1 Bias=2(k−1)−1(k为阶码的位数,例如对于float,Bias=2(8-1)-1=127);
- 阶码为什么采用移码而不用补码?
在浮点数运算时需要比较阶码的大小;补码需要判断符号位,比较大小很麻烦,而移码将有符号数偏移到正整数,易于比较大小;
例如,8位阶码的范围为1~254(0和255为特殊情况),通过偏移127可映射到-126 ~ 127,大小的相对关系不变。- 非规格数实际的阶码为什么是 1 − B i a s 1-Bias 1−Bias?
从非规格化平滑过渡到规格化
- 尾数(f):小数部分。对于规格数,实际的值为
M
=
1.
f
M=1.f
M=1.f;对于非规格数,实际的值为
M
=
0.
f
M=0.f
M=0.f;上述的整数部分在计算机中被隐藏,可节省存储空间(float的有效位数为24(隐含位1+23位尾数);double的有效位数为53(隐含位1+52位尾数))。
总体表达式如下:
( − 1 ) s × 1. f × 2 ( e − b i a s ) ( 规 格 数 ) (-1)^{s}\times 1.f\times 2^{(e-bias)} (规格数) (−1)s×1.f×2(e−bias)(规格数)
( − 1 ) s × 0. f × 2 ( 1 − b i a s ) ( 非 规 格 数 ) (-1)^{s}\times 0.f\times 2^{(1-bias)} (非规格数) (−1)s×0.f×2(1−bias)(非规格数)
除了非规格数和规格数,IEEE 754浮点数还定义了特殊数。以32位为例,三种数据格式汇总如下:
1、非规格数
s | 0000_0000 | f | ( − 1 ) s × 0. f × 2 1 − 127 (-1)^s\times0.f\times 2^{1-127} (−1)s×0.f×21−127 |
---|
2、规格数
s | ≠ 0 \ne0 =0 & ≠ 255 \ne255 =255 | f | ( − 1 ) s × 1. f × 2 e − 127 (-1)^s\times1.f\times 2^{e-127} (−1)s×1.f×2e−127 |
---|
3、特殊数
s | 1111_1111 | = 0 =0 =0 | ( − 1 ) s × ∞ (-1)^s\times\infty (−1)s×∞ |
---|
s | 1111_1111 | ≠ 0 \ne0 =0 | N a N NaN NaN |
---|
各类型数所对应的范围
规格化数的用途:
- 能够表示位于0附近的极小数值;
- 提供了表示数值0的方式。规格化数无法表示0,因为总存在一位为1,而非规格化数在阶码和有尾数全为零时可以表示0,虽然有 ± 0 \pm0 ±0,不过影响不大。
四、总结
IEEE 754标准的编码规则十分巧妙,红字部分都是可以深究的部分,只有亲手推算每种类型的浮点数二进制表示才能体会这里面的细节。
这里可以通过手动输入数值,直观看到计算机内部浮点数的存储形式
五、参考文献
[1]《深入理解计算机系统》第3版
[2]《计算机组成与设计-软件/硬件接口设计》第5版
[3]《数字逻辑与计算机组成》
[4] IEEE 754-2019