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); } }