c语言改错题 有关求一元二次方程ax2+bx+c=0的两个实根

麻烦帮忙看看下面三个程序的区别~~谢谢啦

下列是用于求一元二次方程ax2+bx+c=0的两个实根的三个c程序,分别采用不同的方法或使用不同的精度。其中a=1.0,b=-(1012+1),c=1012。
分别输入并运行这三个程序,并检验结构是否正确,分析原因。
(1)利用求根公式
程序如下:
#include <math.h>
#include <stdio.h>
void main( )
{float a,b,c,p,d,x1,x2;
a=1.0;
b=-(1.0e+12+1.0);
c=1.0e+12;
p=sqrt(b*b-4.0*a*c);
d=2.0*a;
x1=(-b+p)/d;
x2=(-b-p)/d;
printf(“x1=%e\nx2=%e\n”,x1,x2);
}

(2)利用求根公式计算一个实根,然后根据韦达定理计算另一个实根
程序如下:
#include <math.h>
#include <stdio.h>
void main( )
{float a,b,c,p,d,x1,x2;
a=1.0;
b=-(1.0e+12+1.0);
c=1.0e+12;
p=sqrt(b*b-4.0*a*c);
d=fabs(b)/b;
x1=(-b-d*p)/(2.0*a);
x2=c/(a*x1);
printf(“x1=%e\nx2=%e\n”,x1,x2);
}
(3)与(1)一样,利用求根公式,但程序中的变量均使用双精度类型。
#include <math.h>
#include <stdio.h>
void main( )
{double a,b,c,p,d,x1,x2;
a=1.0;b=-(1.0e+12+1.0);c=1.0e+12;
p=sqrt(b*b-4.0*a*c);
d=2.0*a;
x1=(-b+p)/d;
x2=(-b-p)/d;
printf(“x1=%e\nx2=%e\n”,x1,x2);
}

(1)的方法是错的,因为float精度有限,最多只能保存7位有效数字,所以b的值在计算机中保存的实际上是-1.0e+12,那个额外的1是没法保存下来的,不信的话,你可以用下面的代码测试下.
#include <math.h>
#include <stdio.h>
void main( )
{float a,b;
a=1.0e+12+1.0;
b=1.0e+12;
printf("%e\n",a-b);
}

同理,求出的p值理论上应该是sqrt((1e12-4)*1e12),但因为4与1e12相比实在太小,在float的精度下是没法记录的,所以计算机中保存的p值和-b的值是一样的,都是-1e12,所以-b-p只能得到0.求出的x2是0,而正解应该是1.

(3)用了double,精度足够大,可以保存15-16位有效数字,因此b,p的值都是相对精确的,求出的解是正确的.

(2)用了个小技巧,确保了不做-b和p值的减法,而只做加法,这样不会因为float精度不够导致两个理论上有较小差距的数,相减时产生差为0的情况.
温馨提示:内容为网友见解,仅供参考
第1个回答  2009-06-29
b=-(1012+1)表示为指数是b=-(1e3+13) c=1012表示为指数是c=1e3+12
(注:指数形式表示方式:字母e或E之前必须有数字,且e后面的指数必须为整数,如5689.65按指数输出是5.68965e++3)
你的指数都表示错误,下面的就别提了,还要,你写的代码太局限性,a,b,c应该由需要输入,不要固定他们的值
相似回答