fork(2) download
  1. #include<stdio.h>
  2. #include<math.h>
  3. #include<stdlib.h>
  4. #include<time.h>
  5. double GenerateInitialGuess(int); double FindOneRealRoot(double, double, double, double, double);
  6. void ReducePolynomial(double, double, double, double, double, double *,double *,double *);
  7. int SolveQuadraticEquation(double, double, double, double *,double *,double *,double *);
  8. main(void){
  9. int n,root;
  10. double a, b, c, d, guess, m, x1r, x1i, x2r, x2i;
  11. char yn;
  12. do{
  13. printf("Input Cubic Equation like that form :\n 3x^3 + x^2 -2.5x + 2.4 = 0 ->3 1 -2.5 2.4\n 2x^2 - 1 = 0 -> 0 2 0 -1\n");
  14. scanf("%lf %lf %lf %lf%*c", &a, &b, &c, &d);
  15. if(a){
  16. do{
  17. printf("Type positive integer to guess real root\n");
  18. scanf("%d%*c", &n);
  19. if(n>0)
  20. break;}while(1);
  21. guess=GenerateInitialGuess(n);
  22. printf("Set x0 as %lf between %d and %d\n", guess, n, -n);
  23. printf("Try to solve %lfx^3 %+lfx^2 %+lfx %+lf = 0\n",a,b,c,d);
  24. m=FindOneRealRoot(a, b, c, d, guess);
  25. printf("From x0 as %lf. %lf is founded as m.\n", guess, m);
  26. ReducePolynomial(a, b, c, d, m, &b,&c,&d);
  27. printf("Reduced Equation using (x%+lf), We got %lfx^2 %+lfx %+lf = 0\n", -m, b, c, d);}
  28. else
  29. printf("Because a=0, "); /* When a=0, just deal with like quadratic */
  30. printf("Now Try to solve %lfx^2 %+lfx %+lf = 0\n", b, c, d);
  31. root=SolveQuadraticEquation(b, c, d, &x1r,&x1i,&x2r,&x2i);
  32. switch(root){
  33. case -1 : printf("Any numbers in complex are root.\n"); break; /* case -1 and 0 occur when a=0 */
  34. case 0 : printf("There are no roots in complex number.\n"); break;
  35. case 1 : if(a){ /* when a!=0, Reduced polynomial p!=0 so case 1 mean double root */
  36. if(m==x1r) printf("Because Double Root from Quadratic is same as m, there is only one triple root\n x = %lf\n", m); /* for (x-m)^3 */
  37. else printf("There are two roots for Cubic,\n one is x = %lf\n other is x = %lf\n and latter was doble root from Quadratic.\n", m, x1r);} /* for (x-m)(x-x1r)^2 */
  38. else if(b) printf("You input Quadratic equation, and there is only one double root.\n x = %lf\n", x1r); /* a=0 b!=0 -> (x-x1r)^2 */
  39. else printf("Because input eqaution is linear, there is only one root.\n x = %lf\n", x1r); break;
  40. case 2 : if(a){ /* when a!=0 -> m exsist*/
  41. if(x1i) printf("There is one real root,\n x = %lf\n and two complex roots\n x = %lf %+lfi and x = %lf %+lfi\n",m ,x1r,x1i,x2r,x2i);
  42. else if(m==x1r) printf("Because one root from quadratic is same as m, there are two roots.\n one is x = %lf\n other is x = %lf and latter was doble root.\n",x2r,x1r);
  43. else if(m==x2r) printf("Because one root from quadratic is same as m, there are two roots.\n one is x = %lf\n other is x = %lf and latter was doble root.\n",x1r,x2r);
  44. else printf("There are three real roots,\n x = %lf\n x = %lf and\n x = %lf\n",m,x1r,x2r);}
  45. else /* a=0 -> Quadratic*/
  46. if(x1i) printf("There are two complex roots\n x = %lf %+lfi and x = %lf %+lfi\n",x1r,x1i,x2r,x2i);
  47. else printf("There are two real roots,\n x = %lf and\n x = %lf\n",x1r,x2r);
  48. break;}
  49. printf("Check with another Equation?\n");
  50. scanf("%c%*c", &yn);
  51. if (yn=='n'||yn=='N')
  52. break;
  53. }while(1); /*20145030 KST GIST*/
  54. return 0;} /* I bebug it using http://i...content-available-to-author-only...e.com/ / http://i...content-available-to-author-only...e.com/e.js/9ioZ0U is temp address for my code*/
  55. double GenerateInitialGuess(int n){
  56. srand(time(NULL));
  57. double guess=rand()%(2*n+1) - n;
  58. return guess;}
  59. double FindOneRealRoot(double a, double b, double c, double d, double guess){
  60. double acc, x = guess;
  61. do{
  62. while (3*a*pow(x,2)+2*b*x+c==0.0){ /* Try to avoid divide by zero, it will work? I just hope. */
  63. if(a*pow(x,3)+b*pow(x,2)+c*x+d==0.0){
  64. x=floor(x*10000+0.5);
  65. x/=10000;
  66. /* Because acc not enough when (x-m)^3=0, round up */
  67. return x;}
  68. x++;}
  69. acc=(a*pow(x,3)+b*pow(x,2)+c*x+d)/(3*a*pow(x,2)+2*b*x+c); /* adujust version of Newton's methord */
  70. if(fabs(acc)<=0.0000000001)
  71. break;
  72. x-=acc;}while(1);
  73. x=floor(x*10000+0.5);
  74. x/=10000;
  75. return x;}
  76. void ReducePolynomial(double a,double b,double c,double d,double m, double*p,double*q,double*r){
  77. *p=a; *q=b+m*(*p); *r=c+m*(*q);} /* Using Synthetic division */
  78. int SolveQuadraticEquation(double p, double q, double r, double *x1r,double *x1i,double *x2r,double *x2i){
  79. int root; /* -1 for infinity roots */
  80. if(p){
  81. double D=pow(q,2)-4*p*r;
  82. if(D>0.0){ /* two real */
  83. *x1r=(-q+sqrt(D))/2*p;
  84. *x2r=(-q-sqrt(D))/2*p;
  85. *x1i=*x2i=0;
  86. root=2;
  87. }else if(D<0.0){ /* two complex */
  88. *x1r=*x2r=-q/(2*p);
  89. *x1i=sqrt(-D)/(2*p);
  90. *x2i=-sqrt(-D)/(2*p);
  91. root=2;
  92. }else{ /* double root */
  93. *x1r=-q/(2*p);
  94. root=1;}
  95. }else if(q){ /* linear */
  96. *x1r=-r/q;
  97. root=1;
  98. }else if(r)
  99. root=0;
  100. else
  101. root=-1;
  102. return root;}
Success #stdin #stdout 0s 2256KB
stdin
1 3 -8 10 5 n
stdout
Input Cubic Equation like that form :
 3x^3 + x^2 -2.5x + 2.4 = 0 ->3 1 -2.5 2.4
 2x^2 - 1 = 0 -> 0 2 0 -1
Type positive integer to guess real root
Set x0 as 1.000000 between 5 and -5
Try to solve 1.000000x^3 +3.000000x^2 -8.000000x +10.000000 = 0
From x0 as 1.000000. -5.000000 is founded as m.
Reduced Equation using (x+5.000000), We got 1.000000x^2 -2.000000x +2.000000 = 0
Now Try to solve 1.000000x^2 -2.000000x +2.000000 = 0
There is one real root,
 x = -5.000000
 and two complex roots
 x = 1.000000 +1.000000i and x = 1.000000 -1.000000i
Check with another Equation?