fork download
  1. /* (x-1.23456789e10)*(x-1.23456789e-10) = 0
  2.  * 上記式を展開して得られる
  3.  * x^2 -1.23456789e10x +1.52415788 = 0
  4.  * を例にとる。
  5.  */
  6. #include <stdio.h>
  7. #include <math.h>
  8. int main(void) {
  9. double a,b,c;
  10. double x1,x2;
  11. a = +1.0;
  12. b = -1.23456789e10;
  13. c = +1.52415788;
  14.  
  15. /* 解の公式 */
  16. x1 = (-b+sqrt(b*b-4.0*a*c))/(2.0*a);
  17. x2 = (-b-sqrt(b*b-4.0*a*c))/(2.0*a);
  18. printf("解の公式\n");
  19. printf(" x1 : %e\n",x1);
  20. printf(" x2 : %e\n",x2);
  21.  
  22. /* 改良版 */
  23. if (b>0) x1 = (-b-sqrt(b*b-4.0*a*c))/(2.0*a);
  24. else x1 = (-b+sqrt(b*b-4.0*a*c))/(2.0*a);
  25. /* ここで (x-x1)(x-x2) = 0 を考える。
  26.   * これを展開すると
  27.   * x^2 -(x1+x2)x +x1x2 = 0
  28.   * だから、加減算の入らない最終項の x1x2 を使用する。
  29.   * このケースでは x1x2 = c(1.52415788)だから・・・
  30.   */
  31. x2 = c / x1;
  32. printf("改良版\n");
  33. printf(" x1 : %e\n",x1);
  34. printf(" x2 : %e\n",x2);
  35.  
  36. return 0;
  37. }
  38.  
Success #stdin #stdout 0.02s 1720KB
stdin
Standard input is empty
stdout
解の公式
 x1 : 1.234568e+10
 x2 : 0.000000e+00
改良版
 x1 : 1.234568e+10
 x2 : 1.234568e-10