《深入理解计算机系统》(兰德尔 E. 布莱恩特)中对浮点数的描述不容易懂,在这里记录一下,以加深理解。
IEEE(读作“eye-triple-ee”)浮点标准754中,用图1的形式来表示一个数:
符号(sign)——s决定这个数是负数(s=1)还是正数(s=0),而对于数值0的符号位解释,作为特殊情况处理;
尾数(significand)——M决定浮点数的精度,它是一个二进制小数;
阶码(exponent)——E的作用是对浮点数加权,这个权重是2的E次幂(可能是负数),它决定浮点数的取值范围。
对于单精度float,组成形式是:1位符号,8位阶码,23位尾数。
根据阶码,浮点数可以分成三种情况:规格化的,非规格化的或特殊值
当阶码的所有bits,既不全为0,也不全为1时,都属于这种情况。
此时,阶码字段被解释为"以偏置(Bias)形式表示的有符号整数" 。也就是说,阶码所表示的实际数值应是
其中 e 是k 位的阶码所表示的无符号数值,其位表示形式为:" "。
而Bias是一个等于 的偏置值,例如单精度float的偏置是127。由此产生指数的取值范围,对于单精度float是 -126~127 (针对阶码数值为-127或128时的分析,请参考情况2和情况3)。
而尾数字段,则被定义为
其中,f 是n 位的尾数所表示的小数值,满足 ,其二进制表示为:"
",也就是二进制小数点在最高有效位的左边。
有时,这种方式也叫做隐含的以1开头的表示 ,因为我们可以把尾数 M 看成是一个二进制表达式为:" " 的数字。
为什么要用这种表示方式,既然我们总能够调整阶码 E ,使得尾数 M 在范围 之中,那么这种表示方法是一种轻松获得一个额外精度位的技巧——既然第一位总是等于1,那我们就不需要显式地表示它。
由此,规格化形式可以表示的数值 V 的范围是 。
当阶码的所有bits全为0时,所表示的数是非规格化形式。(针对单精度float,阶码值为-127)
在这种情况下,阶码的数值是 。而尾数的值是
,也就是尾数字段的值,开头没有隐含的1。
——那么,为什么非规格化形式为什么将阶码值定义为 ,而不是
?
——因为只有这样,才能从非规格化值平滑转换到规格化值。对此,本文章最后以数字示例做了详细解释。
非规格化形式提供了两种数值0的表示,以单精度float为例,分别是:
+0:0 0000 0000 000 0000 0000 0000 0000 0000;
-0: 1 0000 0000 000 0000 0000 0000 0000 0000。
由此,非规格化形式可以表示的数值 V 的范围是分段函数 ,其中,s 为符号位。
当阶码的所有bits全为1时,所表示的数是特殊值。(针对单精度float,阶码值为128)
(1)无穷 ∞
尾数为0时,该值表示无穷。当两个非常大的数相乘时,或除数为0时,无穷能够表示溢出的结果。
+∞ :0 1111 1111 000 0000 0000 0000 0000 0000
-∞ :1 1111 1111 000 0000 0000 0000 0000 0000
(2)NaN
尾数不为0时,结果值被称为“NaN (Not a Number)”,一些运算的结果不为实数或无穷时,就会返回这样的 NaN 值,比如计算 或
时。
NaN :x 1111 1111 xxx xxxx xxxx xxxx xxxx xxxx
图2展示了假定的8位浮点格式的示例,其中有 k = 4 的阶码位和 n = 3 的小数位。于是可知偏置量 Bias 是 。
可以观察到,最大非规格化数 和最小规格化数
之间的平滑转变。这种平滑性归功于我们对非规格化数的阶码 E 的数值的定义。通过将非规格化数的阶码 E 定义为 1 - Bias,而不是 -Bias,我们可以补偿非规格化数的尾数没有隐含的1。
本文完。