【问题标题】:Using fractional base when summing taylor series causes infinite loop?对泰勒级数求和时使用小数基数会导致无限循环?
【发布时间】:2014-10-01 22:09:50
【问题描述】:

我正在尝试编写一个使用泰勒级数近似 e^x 的程序,如下所示:

我创建了一个函数来进行求和,接受 n(求和的次数)和 x(指数)以及另一个接受数字并返回其阶乘的函数。我认为很简单的东西。我遇到的问题是,当我先输入一个小数 x(例如,0.5、6)时,程序就会挂起。如果我首先输入 (3, 6) 之类的内容,然后在计算之后输入 (.5, 6),我将得到一个无限循环。如果我输入的 x 不是分数,我可以计算任意多次。

我觉得这一定与我对 pow() 函数的调用有关。我想我使用正确(pow(double,int))但它不需要分数或其他东西吗?我不明白。

这是我的代码:

double taylorSeries (double x, int n, double &error)
{
    double sum = 0;
    for (int i=0; i <= n; i++)
        sum += (pow (x, i))/(factorial (i));
    error = (fabs(exp(x) - sum));   
    return sum;
}

long factorial(int n) 
{ 
    long factorial=0;
    for (int i = 0; i <= n; i++){
        if (i == 0)
            factorial = 1;
        else
            factorial = factorial * i;
    }
    return factorial;
}

然后在 main 中调用 taylorSeries 函数如下所示:

cout << "please enter x and n: ";
cin >> x >> n;
cout << "taylor series sum = " ;
cout <<  taylorSeries (x, n, error) << endl;
//cout << "error = " << error;

谁能帮我弄清楚为什么这不起作用?

【问题讨论】:

  • 我不建议使用与数字相同的名称“阶乘”。
  • xmain 中是否定义为double?我猜是int
  • 在调用函数之前验证您的 x 和 n。打印它们。检查您的流是否正确读取它们。
  • factorial 过于复杂但正确。虽然在外部范围内隐藏名称很容易出错。
  • 顺便说一句,从技术上讲,这不是泰勒级数,它是一种从 f(x) 和导数评估 f(x+d) 的方法。在某种意义上它是相似的,它是一个具有阶乘系数的无限级数

标签: c++


【解决方案1】:

不要介意您的算法的某些低效率,您的函数似乎无法返回的最可能原因是 x 解析错误,因此 n 根本没有设置,这意味着它可以保存任何随机价值。

您的线路:

cin >> x >> n;

如果无法正确解析为x,则不会尝试解析下一个数字,因为输入流将处于错误状态。

如果n 没有被初始化,它可以保存任何实际上可能是一个非常大的整数的值。因此,您的算法似乎永远不会返回。

int main()
{
   double x = 0.0;
   int n = 0;
   double error = 0;
   cout << "please enter x and n: ";
   cin >> x >> n;
   if( cin )
   {
         cout << "taylor series sum, x=" << x << " n=" << n << " : ";
        cout <<  taylorSeries (x, n, error) << endl;
        cout << "error = " << error;
   }
   else
   {
       cerr << "invalid input" << endl;
   } 
}

对于更高效的算法:

double taylorSeries (double x, int n, double &error)
{
    double sum = 1;
    double xpow = x; // would start at 1 but we have implemented exponent of 0
    double fact = 1;

    for (int i=1; i <= n; i++)
    {
       fact *= i;
       sum += xpow / fact;
       xpow *= x;
    }

    error = fabs(exp(x) - sum);   
    return sum;
 }

您的factorial 函数在技术上是正确的,直到它溢出为止。

【讨论】:

  • 那么当您说“解析错误”时,您到底是什么意思?抱歉,我只是不确定。所以你已经将 x、n 和 error 初始化为零,这是有道理的。 if (cin) 语句的目的是什么? cin在什么情况下会返回true/false?
  • 如果用户没有输入有效的浮点数或整数。
  • 除了您的回复居高临下之外,我感谢您的帮助。谢谢。如果我有足够的代表,我会投票给你。
猜你喜欢
  • 2018-09-09
  • 2016-02-10
  • 2014-04-03
  • 2013-02-27
  • 1970-01-01
  • 2021-08-12
  • 2021-08-13
  • 2015-05-15
  • 1970-01-01
相关资源
最近更新 更多