2016-10-02 15 views
1

値i(精度)を求め、式1 +1/1!を使用してeを計算する簡単なプログラムを作成するように求められました。 + 1/2! + 1/3! +⋯+ 1! 私は非常に近い値を得ていますが、それでも正しくありません。どこが間違っていたのですか?コードを改善する方法は何ですか?改善のためのループを使用して定数を計算するC++プログラム

#include <iostream> 
using namespace std; 

int main() 
{ 
    double e=0.0; 
    double factorial=0; 
    int i=0;  
    int j,k=0;//counter variables 

    cout<<"Enter degree of accuracy: "; 
    cin>>i; 

    for(j=0;j<=i;j++) //for loop to calculate 'e' 
    { 
     factorial=1;  //To reset factorial to 1 for every value of j 
     for(k=1;k<=j;k++)//for loop to calculate factorial 
     { 
      factorial*=k; 
     } 
     e+=(1/factorial); 
    } 
    cout<<"Value for e given i: "<<e<<endl; 

    system("pause"); 
    return 0; 
} 
+0

なぜ精度を大幅に向上させることができると思いますか?作業しているデータ型は固定精度です。あなたが何をしても1/3! 「double」で計算されるように、数学的な1/6に等しくなることはありません。あなたが望むことができる最大値は、異なる計算ステップからの誤差をやや打ち消すことですが、決して完全に打ち消すことはありません。 –

+1

@ n.m。 - 実際の算術演算では、加算(他の演算の中でも)は連想的です。すなわち、(a + b)+ c = a +(b + c)である。対照的に、浮動小数点演算では加算は**結合ではありません**。つまり、一般的に '(a + b)+ c!= a +(b + c)'です。操作の順序は、エラーの取り消しがなくても、計算の合計エラーに非常に大きな影響を及ぼす可能性があります。そのため、OPは彼のプログラムの精度を向上させることができるのです。詳細は、私の答え(特にカーハン和アルゴリズムへのリンク)を参照してください。 –

+0

@TedHoppあなたは正しいです、Kahanの合計がそうであるように、合計を後方に実行すると結果が改善されます。私の驚いたことに、エラーは最初の最後の重要なビットにしかなかった。 –

答えて

3

2つの領域:

  1. あなたの "修正しない" おそらく丸め誤差によって引き起こされます。降順の正の数列を合計すると、最小値から最大値まで合計することによって、丸め誤差が常に少なくなります。あなたは数値の配列[1/1 !, 1/2 !, 1/3 !, ...、1/i!]を計算し、最後から合計することでこれを行うことができます。同時に、丸め誤差を補正するためのアルゴリズムを見たいかもしれません。良い参考資料は、Kahan summation algorithmのWikipediaの記事です。

  2. あなたは、必要以上に階乗を計算しています。外側のループを通過するたびに、前の値の階乗を計算し終わった(i-1)階乗を計算する必要があります(i-1)。iの階乗を計算する必要があります。したがって、factorialを1にリセットして内部ループを実行するのではなく、前の階乗値にiを掛けて完了させるだけです。 (ああ、およびプログラムの開始時に1ではなく0にfactorialを初期化します。)

また、私は「精度の程度は、」展開における項の数」と同じであるかどうかわからないんだけど"このプログラムの作成を依頼した人は誰でもそれを明確にしたいかもしれません。

関連する問題