Bootstrap

计算机的错误计算(十七)

摘要  本节介绍相减相消概念:两个相近的数相减,则前面相同的数字会相互抵消。在较为复杂的计算过程中,它往往导致损失精度。

       假设

 \left\{\begin{matrix} a = 0.\textcolor{red}{12345678}\,9\times10^{10}, \\ b= 0.\textcolor{red}{12345678}\,8\times10^{10}, \end{matrix}\right.

它们有 8 位相同有效数字。那么,它们的差为

a-b=0.\textcolor{red}{12345678}\,9\times10^{10}-0.\textcolor{red}{12345678}\,8\times10^{10}\\=0.\textcolor{blue}{00000000}1\times10^{10}=0.100000000\times10^2.

这样,相减的过程中抵消掉 8 位数字。即发生了相减相消。为了保留原有的位数,在结尾又添加了 8 个0。 

      上面的案例虽然损失了前面的有效数字,但是并没有损失精度。

      遗憾的是,有时,会损失精度。

例1.  请看计算机的错误计算(十二)中的一个计算案例(保留30 位有效数字)。

       已知

 \pi=\underbrace{3.14159265358979323846264338328}_{30\,\,\textup{digits}}, 

则有

10^{20}+\pi-10^{20}\\ \approx10^{20}+0.\underbrace{314159265358979323846264338328}_{30\,\,\textup{digits}}\times10-10^{20} \\ \approx 0.\textcolor{red}{1}\underbrace{\textcolor{red}{0000000000000000000}}_{19\,\, \textup{zeros}}\underbrace{3141592654}_{\textup{Only} \,\,10\,\, \textup{left}}\times10^{21}-10^{20} \\ =0.\underbrace{\textcolor{blue}{00000000000000000000}}_{20\,\, \textup{zeros}}\underbrace{3141592654}_{\textup{Only} \,\,10\,\, \textup{left}}\times10^{21} \\ =0.\underbrace{3141592654}_{10\,\,\textup{digits} }\times10\\ =0.\underbrace{3141592654}_{10\,\,\textup{digits} \,\,\textup{correct}}\underbrace{00000000000000000000}_{20\,\, \textup{digits} \,\,\textup{incorrect}}\times10.

       下面不妨再分析一下其计算过程。

       显然,由于被减数

 0.\textcolor{red}{1}\underbrace{\textcolor{red}{0000000000000000000}}_{19\,\, \textup{zeros}}\underbrace{3141592654}_{\textup{Only} \,\,10\,\, \textup{left}}\times10^{21} \\=0.\underbrace{\textcolor{red}{10000000000000000000}}_{20\,\, \textup{digits}}\underbrace{3141592654}_{\textup{Only} \,\,10\,\, \textup{left}}\times10^{21}

与减数 

 10^{20}=0.1\dot{0}\times10^{21}=0.\underbrace{\textcolor{red}{10000000000000000000}}_{20 \,\,\textup{digits}}...\times10^{21} 

具有 20 位相同的数字

0.\underbrace{\textcolor{red}{10000000000000000000}}_{20 \,\,\textup{digits}}...\times10^{21},

所以,在相减时,前面的 20 位数字就“相消”了。既然没有了,那么剩下位数不足 30 位,所以需要在其后添加 20个0以补足位数。这样

10^{20}+\pi-10^{20}=\pi

的输出不再是正确答案,而是错误答案

0.\underbrace{3141592654}_{10 \,\,\textup{correct}\,\,\textup{digits}}\underbrace{00000000000000000000}_{20 \,\,\textcolor{red}{\textup{incorrect}}\,\, \textup{digits}}\times10.

于是,相减相消导致精度的损失(实际是20 位有效数字)。

       前面计算机的错误计算(四)(九)中的一元二次方程 与 Tanh函数等的计算问题均是由于相减相消导致的错误计算。

       最后,请问:如何避免相减相消(带来的精度损失)?

;