e023199@cc> gcc 5-2.c -lm e023199@cc> ./a.out Input the coefficients >> 1 3 2 The roots are -1.000000 and -2.000000
の様な簡単な方程式では, 正確な解が求まります.
では,
ではどうでしょうか.
数学的には,
と
が解です. 私の環境では次のようになりました.
e023199@cc> ./a.out IInput the coefficients >> 0.1 10000.0001 10 The roots are -0.00100000000202272 and -100000.00000000000000000
小さいながらも, 真の解と計算機の結果に誤差が現れます.
この場合
と
の差が小さいため, 解の公式の分子の
計算部分で丸め誤差がでています. これを避けるためには, 分子の値が大きい方は
そのまま計算し, 小さい方は解と係数の関係から求める計算をします.
そのようにして書いたプログラムが次です. 私の環境では誤差がでなくなります.
/* File name 5-3.c */
#include <stdio.h>
#include <math.h>
#define BUFFSIZE 1024
main()
{
double a, b, c;
double det;
double ans1, ans2;
char input[BUFFSIZE];
printf("Input the coefficients >> ");
fgets(input, BUFFSIZE, stdin);
sscanf(input, "%lf %lf %lf", &a, &b, &c);
if (a==0){
fprintf(stderr, "a=0 does not make a quadratic equation.\n");
exit(1);
}
det = b*b-4*a*c;
if (det < 0.0){
fprintf(stdout,"The equation has imaginary roots\n");
exit(1);
}
else if (det==0.0){
printf("The root is %f\n", -b/(2.0*a));
return(0);
}
else if (b >=0) {
ans1= (-b-sqrt(det))/(2.0*a);
ans2= c/(a*ans1);
printf("The roots are %17.16f and %17.16f\n", ans1, ans2);
}
else {
ans1= (-b+sqrt(det))/(2.0*a);
ans2= c/(a*ans1);
printf("The roots are %17.16f and %17.16f\n", ans1, ans2);
}
}