(转)指数不同的浮点数相加

来源:互联网 发布:炉石退环境知乎 编辑:程序博客网 时间:2024/05/17 16:43

原文地址:http://learn.akae.cn/media/ch14s04.html

浮点数在计算机中的表示是基于科学计数法(Scientific Notation)的,我们知道32767这个数用科学计数法可以写成3.2767×104,3.2767称为尾数(Mantissa,或者叫Significand),4称为指数(Exponent)。浮点数在计算机中的表示与此类似,只不过基数(Radix)是2而不是10。下面我们用一个简单的模型来解释浮点数的基本概念。我们的模型由三部分组成:符号位、指数部分(表示2的多少次方)和尾数部分(小数点前面是0,尾数部分只表示小数点后的数字)。

图 14.6. 一种浮点数格式

一种浮点数格式

如果要表示17这个数,我们知道17=17.0×100=0.17×102,类似地,17=(10001)2×20=(0.10001)2×25,把尾数的有效数字全部移到小数点后,这样就可以表示为:

图 14.7. 17的浮点数表示

17的浮点数表示

如果我们要表示0.25就遇到新的困难了,因为0.25=1×2-2=(0.1)2×2-1,而我们的模型中指数部分没有规定如何表示负数。我们可以在指数部分规定一个符号位,然而更广泛采用的办法是使用偏移的指数(Biased Exponent)。规定一个偏移值,比如16,实际的指数要加上这个偏移值再填写到指数部分,这样比16大的就表示正指数,比16小的就表示负指数。要表示0.25,指数部分应该填16-1=15:

图 14.8. 0.25的偏移指数浮点数表示

0.25的偏移指数浮点数表示

现在还有一个问题需要解决:每个浮点数的表示都不唯一,例如17=(0.10001)2×25=(0.010001)2×26,这样给计算机处理增加了复杂性。为了解决这个问题,我们规定尾数部分的最高位必须是1,也就是说尾数必须以0.1开头,对指数做相应的调整,这称为正规化(Normalize)。由于尾数部分的最高位必须是1,这个1就不必保存了,可以节省出一位来用于提高精度,我们说最高位的1是隐含的(Implied)。这样17就只有一种表示方法了,指数部分应该是16+5=21=(10101)2,尾数部分去掉最高位的1是0001:

图 14.9. 17的正规化尾数浮点数表示

17的正规化尾数浮点数表示

两个浮点数相加,首先把小数点对齐然后相加:

图 14.10. 浮点数相加

浮点数相加

由于浮点数表示的精度有限,计算结果末尾的10两位被舍去了。做浮点运算时要注意精度损失(Significance Loss)问题,有时计算顺序不同也会导致不同的结果,比如11.0010000+0.00000001+0.00000001=11.0010000+0.00000001=11.0010000,后面加的两个很小的数全被舍去了,没有对计算结果产生任何影响,但如果调一下计算顺序它们就能影响到计算结果了,0.00000001+0.00000001+11.0010000=0.00000010+11.0010000=11.0010001。再比如128.25=(10000000.01)2,需要10个有效位,而我们的模型中尾数部分是8位,算上隐含的最高位1一共有9个有效位,那么128.25的浮点数表示只能舍去末尾的1,表示成(10000000.0)2,其实跟128相等了。在第 2 节 “if/else语句”讲过浮点数不能做精确比较,现在读者应该知道为什么不能精确比较了。


原创粉丝点击