《C程序设计》第五版唐浩强著一书求方程ax²+bx+c=0的解给出的代码中,判断b²-4ac是否等于0是判断它绝对值小于一个人很小的数(如10^-6),他给出的解释是:
“对于判断b2-4ac是否等于0时,要注意:由于disc(即b2-4ac)是实数,而实数在计算和存储时会有一些微小的误差,因此不能直接进行如下判断:“if(disc==0)…”,因为这样可能会出现本来是零的量,由于上述误差而被判别不等于零而导致结果错误。所以采取的办法是判别disc的绝对值(fabs(disc))是否小于一个很小的数(例如10-6),如果小于此数,就认为disc等于0。“
这里在代码中是小于等于10^-6,这是细节问题。
既然 b²-4ac可能出现本来等于0在计算机中可能却不等于0,那么为什么不会出现本来不等于0在计算机中等于0呢?
还有这里说采取的办法是判别disc的绝对值(fabs(disc))是否小于等于10^-6,本来是0计算机中绝对值有两种情况:可能为0,也可能不为0,但绝对值都小于等于10^-6,这证明计算机是可以存绝对值小于等于10^-6却不等于0的数的,那么会不会出现其他情况:本来不等于0在计算机中的结果绝对值小于等于10^-6的数(自然也不会等于0),比如上述绝对值小于等于10^-6却不等于0的数本身,他们在计算机中可以存储,存起来应该不会有误差,这样有以下情况,本身不等于0,在这个程序却把他认定为0。
判断a是否等于0问题也是这样处理的,a只有存储有可能有误差,没有计算有误差,还有,这里判断b²-4ac是否大于0也是是否大于10^-6,很不理解,希望能够详细解释一下,万分感谢。全部代码如下:
#include <stdio.h>
#include <math.h>
int main()
{
double a,b,c,disc,x1,x2,realpart,imagpart;
scanf("%lf,%lf,%lf",&a,&b,&c);
printf("The equation ");
if(fabs(a)<=1e-6)
printf("is not a quadratic\n");
else
{
disc=b*b-4*a*c;
if(fabs(disc)<=1e-6)
printf("has two equal roots:%8.4f\n",-b/(2*a));
else
if(disc>1e-6)
{
x1=(-b+sqrt(disc))/(2*a);
x2=(-b-sqrt(disc))/(2*a);
printf("has distinct real roots:%8.4f and %8.4f\n",x1,x2);
}
else
{
realpart=-b/(2*a);
imagpart=sqrt(-disc)/(2*a);
printf(" has complex roots:\n");
printf("%8.4f+%8.4fi\n",realpart,imagpart);
printf("%8.4f-%8.4fi\n",realpart,imagpart);
}
}
return 0;
}