math - Why does C give different values to Python for this algorithm? -


i wrote short program in c perform linear interpolation, iterates give root of function given number of decimal points. far, function f(x):

    long double f(long double x) {         return (pow(x, 3) + 2 * x - 8);     } 

the program fails converge 1dp value. program updates variables , b, between root of f(x) lies, until , b both round same number @ given precision. using long doubles , above function, debugger shows first 2 iterations:

    = 1.5555555555555556     = 1.6444444444444444 

though should have been:

    = 1.5555555555555556     = 1.653104925053533 

the program fails update values after this. equation linear interpolation i'm using rearranged version of mathematical 1 given here , code i'm using c-version of python program wrote. why c implementation different values, despite same algorithm, , how can fix it?

ok i'm still getting hang of this, below have minimal, complete, , verifiable example:

#include <stdlib.h> #include <stdio.h> #include <math.h>  long double a; long double b; long double c; // values interpolation long double fofa; long double fofb; long double fofc; // values f(a), f(b) , f(c) const int dp = 1; // number of decimal places accurate  long double f(long double x) {     return (pow(x, 3) + 2 * x - 8); }  int main(void) {     = 1; b = 2;     while(roundf(a * pow(10, dp))/pow(10, dp) != roundf(b * pow(10, dp))/pow(10, dp)) { // while , b don't round same number...          fofa = f(a); fofb = f(b); // resolve functions         printf("so f(a) = %g, f(b) = %g\n", (double)fofa, (double)fofb); // print results          c = (b * abs(fofa) + * abs(fofb)) / (abs(fofb) + abs(fofa)); // linear interpolation          fofc = f(c);          if(fofc < 0) {             = c;         }         else if(fofc == 0) {             = c;             break;         }         else {             b = c;         }      }      printf("the root %g, %d decimal places, after %d iterations.\n", (double)a, dp, i); } 

the function abs() (from <stdlib.h>) has signature int abs(int); — getting integers calculations.

you should using long double fabsl(long double); <math.h>.

you should using powl() instead of pow() (long double vs double), , roundl() instead of roundf() (long double vs float).

make sure you're using correct types, in other words.


when you've fixed type problems, still have issue convergence. have helped if had produced mcve (minimal, complete, verifiable example). however, mcve can deduce question:

#include <math.h> #include <stdio.h>  static inline long double f(long double x) {     return(powl(x, 3) + 2 * x - 8); }  int main(void) {     long double = 1.0l;     long double b = 2.0l;     int dp = 6;      while (roundl(a * powl(10, dp)) / powl(10, dp) != roundl(b * powl(10, dp)) / powl(10, dp))     {         long double fofa = f(a);         long double fofb = f(b);         long double c = (b * fabsl(fofa) + * fabsl(fofb)) / (fabsl(fofb) + fabsl(fofa));         long double fofc = f(c);         printf("a = %+.10lf, f(a) = %+.10lf\n", a, fofa);         printf("b = %+.10lf, f(b) = %+.10lf\n", b, fofb);         printf("c = %+.10lf, f(c) = %+.10lf\n", c, fofc);         putchar('\n');          if (fofc < 0.0l)         {             = c;         }         else if (fofc == 0.0l)         {             = c;             break;         }         else         {             b = c;         }     }     printf("result: = %lg\n", a);     return 0; } 

the output is:

a = +1.0000000000, f(a) = -5.0000000000 b = +2.0000000000, f(b) = +4.0000000000 c = +1.5555555556, f(c) = -1.1248285322  = +1.5555555556, f(a) = -1.1248285322 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6531049251, f(c) = -0.1762579238  = +1.6531049251, f(a) = -0.1762579238 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6677455452, f(c) = -0.0258828049  = +1.6677455452, f(a) = -0.0258828049 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6698816424, f(c) = -0.0037639074  = +1.6698816424, f(a) = -0.0037639074 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6701919841, f(c) = -0.0005465735  = +1.6701919841, f(a) = -0.0005465735 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702370440, f(c) = -0.0000793539  = +1.6702370440, f(a) = -0.0000793539 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702435859, f(c) = -0.0000115206  = +1.6702435859, f(a) = -0.0000115206 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702445357, f(c) = -0.0000016726  = +1.6702445357, f(a) = -0.0000016726 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446735, f(c) = -0.0000002428  = +1.6702446735, f(a) = -0.0000002428 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446936, f(c) = -0.0000000353  = +1.6702446936, f(a) = -0.0000000353 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446965, f(c) = -0.0000000051  = +1.6702446965, f(a) = -0.0000000051 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446969, f(c) = -0.0000000007  = +1.6702446969, f(a) = -0.0000000007 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446970, f(c) = -0.0000000001  = +1.6702446970, f(a) = -0.0000000001 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446970, f(c) = -0.0000000000  = +1.6702446970, f(a) = -0.0000000000 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446970, f(c) = -0.0000000000  = +1.6702446970, f(a) = -0.0000000000 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446970, f(c) = -0.0000000000  = +1.6702446970, f(a) = -0.0000000000 b = +2.0000000000, f(b) = +4.0000000000 c = +1.6702446970, f(c) = -0.0000000000 

the reason infinite loop clear; difference between a , b not small fraction. need review convergence criterion. should comparing fofc 0.0 within given number of decimal places — or along lines.


Comments

Popular posts from this blog

javascript - Thinglink image not visible until browser resize -

firebird - Error "invalid transaction handle (expecting explicit transaction start)" executing script from Delphi -

mongodb - How to keep track of users making Stripe Payments -