且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《数值分析(原书第2版)》—— 0.4 有效数字缺失

更新时间:2022-10-02 19:07:38

本节书摘来自华章出版社《数值分析(原书第2版)》一 书中的第0章,第0.4节,作者:(美)Timothy Sauer,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

0.4 有效数字缺失

了解计算机算术的细节的好处在于我们在一个相对好的位置上理解计算机计算中可能出现的陷阱.有一个主要问题以多种形式出现,该问题是由于对近似相等的两个数字相减造成有效数字的位数减少.在这个问题的最简单形式里,这是一个清晰的描述.假设经过大量的努力,作为长计算中的一个部分,我们已经确定两个具有7位有效数位的数,现在需要对它们进行相减:-123.4567123.4566000.0001这个相减问题在开始的时候,有两个具有7位有效数位的数字,但是得到的结果却仅仅只有一位有效数位的精度.尽管这个问题十分容易理解,但是其他造成有效数位缺失的例子就更微妙了,在很多情况下可以通过重新构造计算来避免这个问题.
例0.5 在三位小数的计算机上计算9.01-3.
这个例子依然简单,在这里仅仅作为示例.我们没有像在双精度IEEE标准格式中那样使用具有52位尾数的计算机,而是假设使用只有三位小数的计算机.使用三位计算机意味着整个过程中每个中间计算保存的浮点数只有三位尾数.问题中数据(9.01和3.00)都给定具有三位精度.由于我们将使用三位计算机,乐观的情况下,我们希望结果中也包含三位有效数字.(很显然,由于在整个计算中我们只使用三位数字,所以不能指望得到的有效数字比3位还多.)用手持计算器检查一下,我们发现正确的结果近似是0.0016662=1.6662×10-3,使用三位计算机我们能得到多少位的正确数字?
事实表明,一个有效数位都没有得到.由于9.01≈3.0016662,当我们使用三位有效数字保存中间结果的时候得到3.00.再减去3.00,我们得到的最终结果是0.00.我们的结果中没有一个有效数位是正确的.
令人惊讶的是,有一种方式即便是在这样的三位计算机上,也可以挽救这个计算.造成有效数字丢失的原因是我们显式地减去两个近似相等的数字9.01和3.可以用代数重写表达式,以避免该问题.9.01-3=(9.01-3)(9.01+3)9.01+3=9.01-329.01+3
=0.013.00+3=0.016=0.00167≈1.67×10-3这里,由于下一个数位是6,我们通过向上进位把尾数的最后一位变为7.使用这种方式我们得到所有的三位正确的数位,至少是通过舍入得到正确的三个数位.16通过这个例子我们知道在计算中需要尽可能避免把两个近似相等的数字相减.
在前面例子中使用的方法本质上讲是一个小窍门.通过“共轭等式”进行相乘是一个进行计算重构的窍门.通常会使用一些特定的恒等式,例如三角等式.例如,当x接近0时计算1-cosx就可能会造成有效数字的缺失.让我们比较如下式子对于一组输入数字x进行的计算E1=1-cosxsin2x和E2=11+cosx我们通过对E1的分子和分母同时乘上1+cosx,然后使用三角等式sin2x+cos2x=1.在无穷精度中,两种计算等价.但是MATLAB计算中的双精度数字时我们得到了如下的表:
xE1E21.000000000000000.649223205204760.649223205204760.100000000000000.501252086288580.501252086288570.010000000000000.500012500208480.500012500208340.001000000000000.500000124992190.500000125000020.000100000000000.499999998627930.500000001250000.000010000000000.500000041386850.500000000012500.000001000000000.500044450291340.500000000000130.000000100000000.499600361081320.500000000000000.000000010000000.000000000000000.500000000000000.000000001000000.000000000000000.500000000000000.000000000100000.000000000000000.500000000000000.000000000010000.000000000000000.500000000000000.000000000001000.000000000000000.50000000000000
右边的一列E2中所有显示的数字都是准确的.在E1计算中,由于两个近似相等的数字相减,在x=10-5以下出现了明显的问题,对于输入数字x=10-8或者更小的数字没有得到任何有效数字.
E1式子对于x=10-4已经有几个不正确的位,当x下降,这个问题变得更糟.等价的式子E2不需要对近似相等的数字相减,就没有这样的问题.
二次方程通常面临有效数字缺失的问题.只要知道存在有效数字缺失的问题,同时知道如何重建等式就可以避免这个问题.
例0.6 找到二次等式x2+912x=3的两个根.
首先在双精度算术中试图求解这个问题,例如,使用MATLAB.两个根都没有得到正确的结果,除非我们知道有效数位缺失问题的存在,并知道如何避免这个问题.问题是要找到具有4位有效数位精度的根.目前看起来这是个简单问题.形如ax2+bx+c=0的二次方程的根用如下的二次等式的形式给出:x=-b±b2-4ac2a(0.12)对于我们的问题,转化为x=-912±924+4(3)217使用负号得到根x1=-2.824×1011具有正确的4位有效数字.对于正号的根x2=-912+924+4(3)2MATLAB计算得到0.尽管正确的结果和0非常接近,但是结果中没有得到一个正确的有效数位,尽管用于定义问题的数字是精确的(具有无穷多正确的数位),尽管MATLAB以近似16位有效数字进行计算(这解释了MATLAB的机器精度是2-52≈2.2×10-16).我们该如何解释不能得到x2的精确数位?
答案是有效数字的缺失.很显然,相对来讲,912和924+4(3)近似相等.更精确地,作为保存的浮点数字它们的尾数不仅开始部分相似,而且是完全相同的.当它们相减时,如二次公式所示,很显然结果是0.
这种计算能避免吗?我们必须修复有效数字缺失的问题.计算x2的正确方式是重构二次公式:x2=-b+b2-4ac2a=(-b+b2-4ac)(b+b2-4ac)2a(b+b2-4ac)
=-4ac2a(b+b2-4ac)=-2c(b+b2-4ac)在我们的例子中使用MATLAB代入a,b,c,得到x2=1.062×10-11,这个结果具有题目所需的4位有效数字的精度.
这个例子告诉我们,当a与/或c相对于b非常小的时候,二次公式(0.12)必须小心使用.更准确地说,若4acb2,则b和b2-4ac在量级上相等,其中的一个根就会面临有效数位丢失的问题.如果b在这种情况下是整数,则根必须以如下方式进行计算:x1=-b+b2-4ac2a与x2=-2c(b+b2-4ac)(0.13)注意到,两个公式都没有近似数相减的问题.另一方面,如果b是负数,4acb2,则两个根***进行如下形式的计算:x1=-b+b2-4ac2a与x2=2c(-b+b2-4ac)(0.14)180.4节习题
1.指明对于什么值的x存在两个近似数相减的问题,并找到另外一种形式避免该问题.
(a) 1-secxtan2x(b) 1-(1-x)3x(c) 11+x-11-x
2.计算方程x2+3x-8-14=0的根,保留三位精度.
3.解释如何尽可能精确地计算方程x2+bx-10-12=0的两个根,其中b是一个比100大的数.
4.证明公式(0.14).
0.4节编程问题
1.利用双精度算术(例如使用MATLAB)计算如下式子,其中x=10-1,…,10-14.然后,使用另外一种形式的式子,避免两个近似相等的数字相减的问题,重复这个计算,然后对结果制表.报告对于每个x在原始表达中正确数位的个数.
(a) 1-secxtan2x(b) 1-(1-x)3x
2.寻找p的最小值,使得双精度计算x=10-p中没有正确的有效数位.(提示:首先确定表达式的极限x→0.)
(a) tanx-xx3(b) ex+cosx-sinx-2x3
3.以4位正确的有效数字计算a+a2+b2的值,其中a=-12345678987654321,b=123.
4.以4位正确的有效数字计算c2+d-c的值,其中c=246886422468,d=13579.
5.考虑一个直角三角形,两条直角边长度是3344556600和1.2222222.斜边比最长的直角边长多少?给出至少具有4位正确数位的结果.