编写一个计算欧拉数的算法,直到



我的算法课程教授给了我以下作业:

编写一个 C/C++ 程序,以给定的 eps> 0 精度计算欧拉数 (e) 的值。

提示:数字 e = 1 + 1/1! +1/2! + ... +1/n! + ... = 2.7172 ...可以计算为 序列的元素之和 x_0, x_1, x_2, ..., 其中 x_0 = 1, x_1 = 1+ 1/1 !, x_2 = 1 + 1/1! +1/2 , ...,,只要条件 |x_(i+1) - x_i|>= EPS 有效。

正如他进一步解释的那样,eps是算法的精度。例如,精度可以是 1/100 |x_(i + 1) - x_i|= ( x_(i+1) - x_i ) 的绝对值

目前,我的程序如下所示:

#include<iostream>
#include<cstdlib>
#include<math.h>
#include<vector>
// Euler's number
using namespace std;
double factorial(double n)
{
double result = 1;
for(double i = 1; i <= n; i++)
{
result = result*i;
}
return result;
}
int main()
{
long double euler = 2;
long double counter = 2;
float epsilon = 2;
do
{
euler+= pow(factorial(counter), -1);
counter++;
}
while( (euler+1) - euler >= epsilon);
cout << euler << endl;
return 0;
}

当我实现停止条件 |x_(i+1) - x_i|> = eps (线,其中 while ( (欧拉+1) - 欧拉>= ε);) 输出为 2.5 而不是 2.71828

|x_(i+1) - x_i| > = eps的意思是"x(x_(i+1))的下一个值和x(x_i)的当前值之间的距离大于或等于ε"。

您的代码正在向x添加一个并检查一个非常不同的条件:

(euler+1) - euler >= epsilon

这意味着:"迭代直到euler + 1(不是euler的下一个值!)减去当前值是......",这与原始状态有很大不同。另外,(euler+1) - euler == 1,因此您要检查epsilon是否小于常数 1。

OP 在两次尝试的实现中都遗漏了一些东西。

  • 只要条件|x i+1- xi|>= eps有效,求和就会继续。

    现在,如果我们考虑发布的系列,这种差异是什么样子的?

    x 0 = 1, x 1 = 1 + 1/1!, x 2 = 1 + 1/1! +1/2, ...
    |x 1 - x 0| = 1/1!, |x 2 - x 1| = 1/

    2, ...,|x i- x i - 1| = 1/i

    使条件变为1/i!>= eps

  • 函数factorial在每次迭代时都会多次调用,而我们可以通过几个操作轻松计算欧拉数的新近似

    项/= ++i
    欧拉 += 项

当一个浮点数通过operator<<输出时,它用默认的位数表示。要查看更多内容,我们可以使用输入/输出操纵器,例如std::setprecision.这不会影响该数字的内部表示形式,也不会影响涉及该数字的任何计算的实际精度,它只是一个格式说明符。

double这样的浮点类型的精度(和范围)是有限的,而阶乘增长得非常快。在某个时候,1/i!将非常小,以至于euler += 1/i!在数值上等同于之前的euler值。例如,使用以下变量获得的结果double

1   2
2   2.5
3   2.666666666666666518636930049979127943515777587890625
4   2.70833333333333303727386009995825588703155517578125
5   2.716666666666666341001246109954081475734710693359375
6   2.718055555555555447000415369984693825244903564453125
7   2.71825396825396836675281520001590251922607421875
8   2.718278769841270037233016410027630627155303955078125
9   2.71828152557319224769116772222332656383514404296875
10   2.718281801146384513145903838449157774448394775390625
11   2.71828182619849290091451621265150606632232666015625
12   2.71828182828616871091753637301735579967498779296875
13   2.718281828446759362805096316151320934295654296875
14   2.71828182845823018709552343352697789669036865234375
15   2.718281828458994908714885241352021694183349609375
16   2.7182818284590428703495490481145679950714111328125
17   2.71828182845904553488480814849026501178741455078125
18   2.71828182845904553488480814849026501178741455078125
19   2.71828182845904553488480814849026501178741455078125
20   2.71828182845904553488480814849026501178741455078125
2.718281828459045090795598298427648842334747314453125    <--- std::numbers::e

请注意,计算值和std::numbers::e之间的差异大致为 +4.4e-16(它实际上是下一个可表示的double值)。

完整的代码(包括所有需要的初始化)留给读者编写。

相关内容

  • 没有找到相关文章

最新更新