首页 » 算法技术手册 » 算法技术手册全文在线阅读

《算法技术手册》浮点计算

关灯直达底部

计算机是有限机,设计初衷是对存储在CPU寄存器的值进行基本计算。随着计算机架构从20世纪70年代流行的8位Intel处理器增长到如今广泛接受的64位架构(如Intel的Itanium以及Sun的Sparc处理器),寄存器的大小也发生了变化。对存储在寄存器的整数来说,例如ADD、MULT、DIVIDE和SUB这些基本操作通常都由CPU支持。浮点运算单元(FPU)能够高效地处理浮点数,当然这些浮点数必须遵守IEEE关于二进制浮点算数的标准(IEEE754)。

整数值(如布尔型、8位短整型,以及16位或者32位整数)的计算通常能被处理器高效地执行。高效程序一般都会利用浮点数和整数算术的性能差异来改善程序的执行效率。当编写含有浮点计算的程序的时候,有一些问题是软件开发人员必须注意的(Goldberg,1991)。我们在这本书的算法和代码中也会考虑到这些问题,下面我们就看看这些重要的问题究竟是什么。

舍入的错误

由于浮点数本身的表示方法,任何使用浮点数的计算都必须关注一下舍入的错误。一般来说,最初设计浮点数的时候,是用一个有限数来近似地表示一个实数,也许这个实数是无限小数。表3-1给出了3.88的浮点表示和特有的表示。

用1位来表示符号,8位表示指数,23位表示尾数(也就是有效数)。在Java的浮点表示中,“将指数部分作为一个正数,然后从这个正数中减去一个基准值,得到2的幂。对于一个浮点数来说,这个基准值是126”(Venners,1996)。指数部分是128,所以实际的指数值是128-126,或2。

为了得到最高的精确度,尾数必须是规格化的,所以最左边的数字永远是1。在之前的例子中,尾数是.[1]11110000101000111101100=[1/2]+1/4+1/8+1/16+1/32+1/1 024+1/4 096+1/65 536+1/131 072+1/262 144+1/524 288+1/2 097 152+1/4 194 304,在进位之后,这个值是0.9700000286102294921875。

因此,当使用这种表示方法存储3.88f时,近似值是+1*0.9700000286102294921875*22,也就是3.88000011444091796875。固有误差是~0.0000001。描述浮点复查的最常用方法是使用相对误差,相对误差计算的是绝对误差和期望值的一个比率。在这里,相对误差是0.0000001144091796875/3.88,或者写作2.9E-8。低于百万分之一的相对误差是相当普遍的。