我的 C++ 程序无法为欧拉数计算这个系列
My C++ program has trouble calculating this series for Euler's number
这是我为解决上述系列问题而编写的 C++ 程序:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int factorial(int a)
{
if (a > 1)
return a * factorial(a - 1);
else
return 1;
}
float series(float x, int n, float b)
{
if (abs(pow(x, n) / factorial(n)) < pow(10, -6) || abs(pow(x, n) / factorial(n)) == pow(10, -6)) { return b; }
else return b = (pow(x, n) / factorial(n)) + series(x, n + 1, b);
}
int main()
{
float x;
cout << "Enter x: "<<endl;
cin >> x;
cout << "E^x = " << series(x,0,0);
system("pause");
return 0;
}
当 abs(x) < 2 时工作正常,但当 abs(x) >= 2 时出现此错误:
Unhandled exception at 0x00F02539 in 33b.exe: 0xC00000FD: Stack
overflow (parameters: 0x00000001, 0x00F22FF8). occurred
我想知道为什么会发生这种情况,我该如何解决?
你的问题是递归太深。考虑循环。
float series(float x)
{
const float epsilon = 1e-6f;
double error = 1;
double res = 1.f;
int iter = 1;
while (abs(error) > epsilon) {
error *= (x / iter++);
res += error;
cout << error << endl;
}
return res;
}
int main()
{
cout << "E^x = " << series(3);
system("pause");
return 0;
}
为了更清楚地了解发生了什么:
当您在另一个函数内部调用一个函数时,父函数的上下文将被保存以为新上下文腾出空间。当你做百万次inception的时候,负责保存这些context的内存栈满了溢出了。
这是堆栈溢出。
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int factorial[200];
int Factorial(int a)
{ if(a>0){
factorial[a]=a * factorial[a-1];
return factorial[a];
}
else
factorial[a]=1;
return 1;
}
double series(double x, int n, double b)
{ double temp=(abs(pow(x, n)) / Factorial(n));
if (temp <= 0.000001) { return b; }
else return (temp + series(x, n + 1, b));
}
int main()
{
float x;
cout << "Enter x: "<<endl;
cin >> x;
cout << "E^x = " << series(x,0,0);
system("pause");
return 0;
}
嗯,这个解决方案有效。我所做的只是我把你的代码删除了 abs(pow(x, n) / factorial(n)) 无论它在哪里重复并初始化为一个新的变量 temp。然后代替 < || == 你可以直接把 <=.而不是每次都调用一个函数来计算 .000001,您可以只给出该值以进一步减少时间。但是我认为代码可能不起作用的原因是递归太多。所以对于阶乘,我使用动态规划来降低它的复杂性。上面的代码工作得很好。
这是我为解决上述系列问题而编写的 C++ 程序:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int factorial(int a)
{
if (a > 1)
return a * factorial(a - 1);
else
return 1;
}
float series(float x, int n, float b)
{
if (abs(pow(x, n) / factorial(n)) < pow(10, -6) || abs(pow(x, n) / factorial(n)) == pow(10, -6)) { return b; }
else return b = (pow(x, n) / factorial(n)) + series(x, n + 1, b);
}
int main()
{
float x;
cout << "Enter x: "<<endl;
cin >> x;
cout << "E^x = " << series(x,0,0);
system("pause");
return 0;
}
当 abs(x) < 2 时工作正常,但当 abs(x) >= 2 时出现此错误:
Unhandled exception at 0x00F02539 in 33b.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00F22FF8). occurred
我想知道为什么会发生这种情况,我该如何解决?
你的问题是递归太深。考虑循环。
float series(float x)
{
const float epsilon = 1e-6f;
double error = 1;
double res = 1.f;
int iter = 1;
while (abs(error) > epsilon) {
error *= (x / iter++);
res += error;
cout << error << endl;
}
return res;
}
int main()
{
cout << "E^x = " << series(3);
system("pause");
return 0;
}
为了更清楚地了解发生了什么:
当您在另一个函数内部调用一个函数时,父函数的上下文将被保存以为新上下文腾出空间。当你做百万次inception的时候,负责保存这些context的内存栈满了溢出了。
这是堆栈溢出。
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int factorial[200];
int Factorial(int a)
{ if(a>0){
factorial[a]=a * factorial[a-1];
return factorial[a];
}
else
factorial[a]=1;
return 1;
}
double series(double x, int n, double b)
{ double temp=(abs(pow(x, n)) / Factorial(n));
if (temp <= 0.000001) { return b; }
else return (temp + series(x, n + 1, b));
}
int main()
{
float x;
cout << "Enter x: "<<endl;
cin >> x;
cout << "E^x = " << series(x,0,0);
system("pause");
return 0;
}
嗯,这个解决方案有效。我所做的只是我把你的代码删除了 abs(pow(x, n) / factorial(n)) 无论它在哪里重复并初始化为一个新的变量 temp。然后代替 < || == 你可以直接把 <=.而不是每次都调用一个函数来计算 .000001,您可以只给出该值以进一步减少时间。但是我认为代码可能不起作用的原因是递归太多。所以对于阶乘,我使用动态规划来降低它的复杂性。上面的代码工作得很好。