5.1. 浮点数存储方式和数值范围

计算机中的数据都以二进制形式保存,但浮点数的表示方式比较特殊,不能像整数那样直接采用补码格式。因此,IEEE定义了两种基础浮点格式:单精度和双精度。单精度浮点数对应C语言中的float类型,宽度为32位;双精度浮点数对应C语言中的double类型,宽度为64位。二者的组织方式如图4-1所示。

单精度和双精度的组织格式

单精度浮点数由3部分构成:1位符号s(0表示正数,1表示负数)、8位偏置指数e和23位小数f。双精度浮点数同样由3部分构成:1位符号s、11位偏置指数e和52位小数f。根据偏置指数e的取值不同,浮点数的计算方式和可表示范围也不同,通常可分为以下3类。

5.1.1. 规格化的值

这是最常见的浮点表示形式。当偏置指数e既不全为0,也不全为1时(单精度中全1为0xFF,双精度中全1为0x7FF),如图4-2所示,该浮点数表示规格化的值。此时数值计算公式如下:

单精度浮点数:(-1)sx2e-127x1.f

双精度浮点数:(-1)sx2e-1023x1.f

e区域既不为0也不为1

例如,某个浮点寄存器低32位中保存的二进制值为:

0100 0000 1011 1000 0000 0000 0000 0000
||_________|___________________________|
s 	e(8)                    f(23)

按前述单精度浮点数公式计算,它对应的十进制浮点数约为5.75。其中,s为0,e为129(二进制10000001),f为3670016(二进制011 10000000 0000 0000 0000)。

5.1.2. 非规格化的值

当偏置指数e全为0时,如图4-3所示,该数表示非规格化的值,主要用于表示0以及非常接近0的数。具体来说,当f全为0时,如果s为0,则表示+0.0;如果s为1,则表示-0.0。当f不全为0时,单精度浮点数的计算公式为:

(-1)sx2-126x0.f

此时得到的是一个非常接近0的数。

e区域为0

5.1.3. 正负无穷大或NaN

当偏置指数e全为1时,可以表示无穷大或非数字(Not a Number,NaN),如图4-4所示。具体规则是:当f全为0时,若s为0,则表示正无穷大+INF;若s为1,则表示负无穷大-INF。当f不全为0时,结果称为NaN。某些运算结果既不能表示为实数,也不能表示为无穷大时,就会返回NaN。

e区域既为1