2016-11-18 3 views
0
double taylor_log(double x, unsigned int n){ 
double tmp; 
double sum = 0; 
if(x < 1){ 
    int j = 2; 
    x = 1 - x; 
    tmp = x; 
    sum = -x; 
    for(unsigned int i = 1; i < n; i++){ 
     sum -= ((tmp *= x)/j); 
     j++; 
    } 
    return sum; 
} 
else if (x >= 1){ 
    tmp = ((x-1)/x); 
    for(unsigned int i = 1; i <= n; i++){ 
     sum += (tmp/i); 
     tmp *= ((x-1)/x); 
    } 
    return sum; 

これは正しく動作するテイラー級のログです。 この式を使用して、数値の指数関数を得る。 formula for mypow() これは今私の問題は、私は私の機能のために例えば30回の反復を置けば数)(POWよりも高いことであるPOWmypow()トラフ継続分数とtaylorseriesはpow()より大きい数値を返します

double taylor_pow(double x, double y, unsigned int n){ 
double sum = 1.0; 
int fac = 1; 
double exp = y; 
double lna = taylor_log(x, n); 
for(unsigned int i = 1; i <= n; i++){ 
    fac *= i; 
    sum += (exp * lna/fac); 
    exp *= y; 
    lna *= taylor_log(x, n); 
} 
return sum; 

} ための私のコードです。たとえばpow(2,3)= 8、20回の反復での結果は8.0007 ...そしてその成長です。すべての応答のThans。

+0

成長している場合:これは累積丸め問題のように聞こえます。中間計算の結果は、一時変数に正確に収まらない場合があります。あなたは単にマシンの精度限界に遭遇しているだけです。私は、ほとんどの場合、追加と乗算(実験: 'x = 0.5'を入力としたときの結果、' tailor_log'はあなたに否定的な結果を与えるでしょうか? 。このような場合は、丸め誤差を避けるためにいくつかのスマートな方法(再定式化)を見つける必要があります。 – Evert

答えて

0

int facがオーバーフローしています。それをlong doubleに変更しました。

32ビット符号付きintは最大12の値しか保持しませんが、80または128ビットlong doubleは2000などの値を保持できます。

+0

128ビットの浮動小数点数は非常にまれです! long doubleはコンパイラの動作です。 – Stargateur

+0

@Stargateurはい、それは当てはまりますが、64ビットは2^3の許容値を得るには十分であり、80ビットはそれ以上です。 –

関連する問題