最简单的解决方案使用浮点。
如果你想提高你的准确性,应该先把最小的项加在一起。我在其他地方发布了一个递归解决方案来执行此操作,但随后是一个简单的非递归解决方案,并与另一个流行的答案进行了比较。
将 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