2

これまでのところ、テイラー級数を使用してcos(x)関数を計算するプログラムを作成しようとしています。

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;

}

私の例では、cos(90)を計算するために、角度= 90、繰り返し= 20を使用していますが、値を無限に近づけ続けるのは無意味です。助けていただければ幸いです。

4

2 に答える 2

3

一つには、角度はラジアンであるため、90度の角度の場合は、を渡す必要がありますM_PI/2

また、階乗のように些細なものの再帰関数は避ける必要があります。反復的に記述するのに1/4の労力がかかり、パフォーマンスが大幅に向上します。実際には必要ありません。階乗を一時変数に保持し、2*i*(2*i-1)各ステップで乗算するだけです。このステップでは、表現可能性/精度の壁にすぐにぶつかることを覚えておいてください。

powまた、実際に-1の累乗を呼び出す必要はありません。i単純なものi%2?1:-1で十分です。このようにすると、速度が速くなり、増加しても精度が低下しませんi

ああ、作らないでくださいi float、それは整数です、それを整数にしてください。あなたはそれなりに精度をたくさん漏らしている、なぜそれを悪化させるのか。

そして、それをすべて締めくくりに、あなたはおよそcos0に近づいていますが、それをと呼んでいpi/2ます。これを行うと、非常に高いエラーが発生します。

于 2011-08-27T02:35:09.690 に答える
0

テイラー級数は、引数がラジアンである数学余弦関数用です。したがって、90は、おそらくここで意味すると思っていた意味ではありません。

さらに、このシリーズでは、引数が0から長いほど、より多くの項が必要になります。一般に、連続する項が小さくなり、順番よりも多くなる前に、項の数は引数のサイズに匹敵する必要があります。収束するために。20は、x=90に使用する用語が残念ながら少ないです。

もう1つの問題は、階乗をとして計算することですint。階乗関数は非常に速く成長します-すでに13のために!通常のC int(32ビットマシン上)はオーバーフローするため、6番目以降の条件はとにかく完全に間違っています。

実際、階乗と90の累乗はすぐに大きくなりすぎて、doublesとしても表すことができなくなります。級数が収束するのを見る機会が必要な場合は、各項を最初から計算するのではなく、次のような式を使用して前の項から導出する必要があります。

nextTerm = - prevTerm * x * x / (2*i-1) / (2*i);
于 2011-08-27T02:38:20.383 に答える