最も単純なソリューションでは、浮動小数点を使用します。
精度を向上させたい場合は、最初に最小の項を合計する必要があります。これを行うために再帰的なソリューションを他の場所に投稿しましたが、単純な非再帰的なソリューションが続き、別の一般的な回答と比較されます。
2 つの方法 (float を使用) を double を使用した同じ方法 (図示せず) と比較して、相対誤差を決定しました。「最小項を最初に合計する」は、「最大項を最初に合計する」に勝ることはありませんでした。
注:
1+1/2!+1/3!.......+1/n! = (( (((1/n + 1)/(n-1) + 1)/(n-2) + 1) ... )/2 + 1/1
float f1(int n) { // sum smallest terms together first
float sum = 0.0;
while (n >= 1) {
sum = (1.0f + sum) / n;
n--;
}
return sum;
}
float f2(int n) { // sum largest terms together first
float term = 1.0;
float f = 1.0;
int i;
for (i = 2; i <= n; i++) {
term *= 1.0f / i;
f += term;
}
return f;
}
void ftest(int n) {
double y = (d1(n) + d2(n))/2; // d1,d2 is a double version of f1,f2 (not shown)
printf("f1 %2d %.8e %+e\n", n, f1(n), (f1(n) - y)/y);
printf("f2 %2d %.8e %+e\n", n, f2(n), (f2(n) - y)/y);
}
int main() {
int i;
for (i = 5; i < 9; i++)
ftest(i);
return 0;
}
f1 5 1.71666670e+00 +1.851795e-08 // The exact answer is 1.716666...
f2 5 1.71666658e+00 -5.092436e-08
f1 6 1.71805549e+00 -4.008979e-08
f2 6 1.71805549e+00 -4.008979e-08
f1 7 1.71825397e+00 +1.101240e-09
f2 7 1.71825385e+00 -6.827691e-08
f1 8 1.71827877e+00 -2.422694e-09
f2 8 1.71827865e+00 -7.179985e-08