سؤال

I'm trying to make a program to calculate the cos(x) function using taylor series so far I've got this:

int factorial(int a){

if(a < 0)
    return 0;
else if(a==0 || a==1)
    return 1;
else
    return a*(factorial(a-1));
}

double Tserie(float angle, int repetitions){
    double series = 0.0;
    float i;

for(i = 0.0; i < repeticiones; i++){
    series += (pow(-1, i) * pow(angle, 2*i))/factorial(2*i);
    printf("%f\n", (pow(-1, i) * pow(angle, 2*i))/factorial(2*i));
}
return series;

}

For my example I'm using angle = 90, and repetitions = 20, to calculate cos(90) but it's useless I just keep getting values close to the infinite, any help will be greatly appreciated.

هل كانت مفيدة؟

المحلول

For one thing, the angle is in radians, so for a 90 degree angle, you'd need to pass M_PI/2.

Also, you should avoid recursive functions for something as trivial as factorials, it would take 1/4 the effort to write it iteratively and it would perform a lot better. You don't actually even need it, you can keep the factorial in a temporary variable and just multiply it by 2*i*(2*i-1) at each step. Keep in mind that you'll hit a representability/precision wall really quickly at this step.

You also don't need to actually call pow for -1 to the power of i, a simple i%2?1:-1 would suffice. This way it's faster and it won't lose precision as you increase i.

Oh and don't make i float, it's an integer, make it an integer. You're leaking precision a lot as it is, why make it worse..

And to top it all off, you're approximating cos around 0, but are calling it for pi/2. You'll get really high errors doing that.

نصائح أخرى

The Taylor series is for the mathematical cosine function, whose arguments is in radians. So 90 probably doesn't mean what you thought it meant here.

Furthermore, the series requires more terms the longer the argument is from 0. Generally, the number of terms need to be comparable to the size of the argument before you even begin to see the successive terms becoming smaller, and many more than that in order to get convergence. 20 is pitifully few terms to use for x=90.

Another problem is then that you compute the factorial as an int. The factorial function grows very fast -- already for 13! an ordinary C int (on a 32-bit machine) will overflow, so your terms beyond the sixth will be completely wrong anyway.

In fact the factorials and the powers of 90 quickly become too large to be represented even as doubles. If you want any chance of seeing the series converge, you must not compute each term from scratch but derive it from the previous one using a formula such as

nextTerm = - prevTerm * x * x / (2*i-1) / (2*i);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top