C语言算法探究之(二):算法的准确性

 

本篇是接着上一篇而写的。

数学本身是非常严密的,在进行数学推导的过程中,一般要用到一些运算规则、恒等变换、公式变形等,而变换前后的式子是等价的。但在实际运算过程中,数学上完全等价的式子,其运算结果却差异很大。下面再举个例子说明:

使用通常的求根公式,即:

 

来求解一元二次方程:

 

 

 

的两个实根。

程序如下:

 1 // exp2.cpp : Defines the entry point for the console application.
2 //
3
4 #include "stdafx.h"
5 #include "math.h"
6
7 int main(int argc, char* argv[])
8 {
9 double x1,x2;
10 x1=(pow(10,18)+1+sqrt((pow(10,18)+1)*(pow(10,18)+1)-4*1*pow(10,18)))/2;
11 x2=(pow(10,18)+1-sqrt((pow(10,18)+1)*(pow(10,18)+1)-4*1*pow(10,18)))/2;
12 printf("x1=%e\n",x1);
13 printf("x2=%e\n",x2);
14 return 0;
15 }

结果如下:

经检验可以发现:x1=1.0e+018是方程的跟,而x2=0.0并不满足原方程。

这个例子表明,理论上的解题方案在有些情况下并不能使用,实际上,一元二次方程

的求根公式

对于一般的系数a,b,c来说可以使用,但如果对于某些a,b,c使求根公式分子中的两项(-b)和很接近时,计算结果就会严重丢失有效数字,在这种情况下就不能简单的使用求根公式了。

一般来说,对于一元二次方程可以用以下方法求出两个实根:利用求根公式先计算一个可靠的实根,目的是使求根公式分子中的两项为同号相加,从而避免了两个同号数相减的情况,然后利用韦达定理计算另一个实根:

 

 

其中sgn(b)为b的符号函数。

 

 

 

你可能感兴趣的:(C语言)