2.3.3 IEEE 754浮点数标准
直到20世纪80年代初,浮点数表示格式还未统一,不同架构的计算机之间进行数据传送或程序移植时,必须进行数据格式的转换,数据格式转换会导致运算结果的不一致。因而,20世纪70年代后期,IEEE成立委员会着手制定浮点数标准,1985年完成了浮点数标准IEEE 754的制定。
目前,几乎所有计算机都采用IEEE 754标准。该标准提供了两种基本格式,即32位单精度格式和64位双精度格式,如图2.4所示。
32位单精度格式中包含1位符号s、8位阶码e和23位尾数f;64位双精度格式包含1位符号s、11位阶码e和52位尾数f。其基数隐含为2;尾数用原码表示,第一位总为1,因而可在尾数中缺省第一位的1,称为隐藏位,使得单精度格式的23位尾数实际上可表示24位有效数字,双精度格式的52位尾数实际上可表示53位有效数字。特别要注意的是,IEEE 754规定隐藏位“1”的位置在小数点之前,与例2.21中给出的不一样。
图2.4 IEEE 754浮点数格式
IEEE 754标准中,阶码用移码形式,偏置常数并不是通常n位移码所用的2n-1,而是(2n-1-1),因此,单精度浮点数和双精度浮点数的偏置常数分别为127和1023。
IEEE 754标准规定,一些特殊的位序列(如阶码为全0或全1)具有特殊含义。表2.2给出了对各种形式的数的解释。
表2.2 IEEE 754浮点数的解释
表2.2对IEEE 754格式的数分类如下。
1.全0阶码全0尾数:+0/-0
IEEE 754的零有两种:+0和-0。零的符号取决于数符s。一般情况下+0和-0是等效的。
2.全1阶码全0尾数:+∞/-∞
引入无穷大数可表示一些特殊的运算结果,并为程序提供错误检测功能。+∞在数值上大于所有有限数,-∞则小于所有有限数,无穷大数既可作为操作数,又可能是运算的结果。当操作数为无穷大时,系统可以有两种处理方式。
• 产生不发信号的非数NaN,如+∞+(-∞)、+∞-(+∞)、∞/∞等。
• 产生明确的结果,如5+(+∞)=+∞、(+∞)+(+∞)=+∞、5-(+∞)=-∞、(-∞)-(+∞)=-∞等。
3.全1阶码非0尾数:NaN(Not a Number)
NaN(Not a Number)表示一个没有定义的数,称为非数,分为不发信号(quiet)和发信号(signaling)两种非数。有的书中把它们分别称为“静止的NaN”和“通知的NaN”。表2.3给出了能产生不发信号(静止的)NaN的计算操作。
表2.3 产生不发信号NaN的计算操作
可用尾数取值的不同来区分是“不发信号NaN”还是“发信号NaN”。例如,当最高有效位为1时,为不发信号NaN,当结果产生这种非数时,不抛出异常;当最高有效位为0时,为发信号NaN,当结果产生这种非数时,则抛出异常。NaN的尾数是非0数,除第一位有定义外,其余位都没有定义,因此可用其余位来指定具体的异常条件。如表2.3所示,一些没有数学解释的计算(如0/0、0×∞等)会产生一个非数。
4.阶码非全0且非全1:规格化非0数
阶码范围为1~254(单精度)和1~2046(双精度)的数是一个正常的规格化非0数。根据IEEE 754的定义,规格化数指数(阶)的范围是-126~+127(单精度)和-1022~+1023(双精度),浮点数的值的计算公式分别为:
(-1)s×1.f × 2e-127和(-1)s×1.f × 2e-1023
5.全0阶码非0尾数:非规格化数
非规格化数的特点是阶码为全0,尾数高位有一个或几个连续的0,但不全为0。因此非规格化数的隐藏位为0,并且单精度和双精度浮点数的阶分别为-126或-1022,故浮点数的值分别为:
(-1)s×0.f ×2-126和(-1)s×0.f×2-1022
非规格化数可用于处理阶码下溢,使得出现比最小规格化数还小的数时程序也能继续进行下去。当运算结果的阶太小(比最小能表示的阶还小,即小于-126或小于-1022)时,尾数右移1次,阶码加1,如此循环,直到尾数为0或阶达到可表示的最小值(-126或-1022)。这个过程称为逐级下溢。因此,逐级下溢的结果就是使尾数变为非规格化形式,阶变为最小负数。例如,当一个十进制运算系统的最小阶为-99时,以下情况需进行阶码逐级下溢。
• 2.0000×10-26×5.2000×10-84=1.04×10-109→0.1040×10-108→0.0104×10-107→…→0.0
• 2.0002×10-98-2.0000×10-98=2.0000×10-102→0.2000×10-101→0.0200×10-100→0.0020×10-99
图2.5展示了加入非规格化数后IEEE 754单精度的表数范围的变化。图中将可表示数以[2n,2n+1]的区间分组。区间[2n,2n+1]内所有数的阶相同,都为n,而尾数部分的变化范围为1.00…0~1.11…1,这里小数点前的1是隐藏位。对于32位单精度规格化数,因为尾数的位数有23位,故每个区间内数的个数相同,都是223个。例如,在正数范围内最左边的区间为[2-126,2-125],在该区间内,最小规格化数为1.00…0×2-126,最大规格化数为1.11…1×2-126。在该区间中的各个相邻数之间具有等距性,其距离为2-23×2-126,该区间右边相邻的区间为[2-125,2-124],区间内各相邻数间的距离为2-23×2-125。由此可见,每个右边区间内相邻数间的距离总比左边一个区间的相邻数距离大一倍,因此,离原点越近的区间,其内的数间隙越小。
图2.5 IEEE 754中加入非规格化数后表数范围的变化
图2.5a所示为未定义非规格化数时的情况,在0和最小规格化数2-126之间有一个间隙未被利用。图2.5b所示为定义了非规格化数的情况,非规格化数就是在0和2-126之间增加的223个附加数,这些相邻附加数之间与区间[2-126,2-125]内的相邻数等距,所有非规格化数具有与区间[2-126,2-125]内的数相同的阶,即最小阶(-126),尾数部分的变化范围为0.00…0~0.11…1,隐含位为0。
例2.22 将十进制数-0.75转换为IEEE 754的单精度浮点数格式表示。
解:(-0.75)10=(-0.11)2=(-1.1)2×2-1=(-1)s ×1.f×2e -127,所以 s=1, f=0.100…0, e=(127-1)10=(126)10=(0111 1110)2,单精度浮点数为1 0111 1110 10000000…0000000,用十六进制表示为BF400000H。
例2.23 求IEEE 754单精度浮点数C0A0 0000H的真值。
解:求一个机器数的真值,就是将该数转换为十进制数。首先将C0A0 0000H展开为一个32位单精度浮点数:1 10000001 010 0000…0000。据IEEE 754单精度浮点数格式可知,符号s=1, f=(0.01)2=(0.25)10,阶码e=(10000001)2=(129)10,其值为(-1)s ×1.f×2e -127=(-1)1×1.25×2129-127=-1.25×22=-5.0。
IEEE 754标准的单精度和双精度规格化数的特征参数如表2.4所示。
表2.4 IEEE 754浮点数格式参数
IEEE 754用全0阶码和全1阶码表示一些特殊值,如0、∞和NaN,因此,除去全0和全1阶码后,规格化单精度和双精度格式的阶码个数分别为254和2046,最大阶分别为127和1023。单精度规格化数的个数约为2×254×223=1.98×231,双精度规格化数的个数约为2×2046×252=1.99×263。根据单精度和双精度格式的最大阶分别为127和1023,可以得出数的量级范围分别为10-38~10+38和10-308~10+308。单精度和双精度格式规格化数中,最小阶分别为-126和-1022,而非规格化数的阶总是-126和-1022,因而单精度浮点格式的最小可表示数为0.0…01×2-126=2-23×2-126=2-149,而双精度格式的最小可表示数为2-52×2-1022=2-1074。
IEEE 754规定了单精度扩展和双精度扩展两种格式的最小长度和最小精度。双精度扩展格式必须至少具有64位有效数字,并总共占用至少79位,但未规定其具体格式。
例如,SPARC和PowerPC处理器中采用128位扩展双精度浮点数格式,包含1位符号位s、15位阶码e(偏置常数为16 383)和112位尾数f,采用隐藏位,所以有效位数为113位。
又如,Intel x87 FPU采用80位双精度扩展格式,包含4个字段:1位符号位s、15位阶码e(偏置常数为16 383)、1位显式首位有效位(explicit leading significant bit)j和63位尾数f。Intel采用的这种扩展浮点数格式与IEEE 754规定的单精度和双精度浮点数格式的一个重要的区别是,它没有隐藏位,有效位数共64位。