【问题标题】:How to calculate a sum of sequence e^(-x) with accuracy E=0.0001?如何以 E=0.0001 的精度计算序列 e^(-x) 的总和?
【发布时间】:2015-03-26 20:27:27
【问题描述】:

所以我可以计算一个没有精度E的序列和。

    int t=1, x, k;
    float sum, a, result, factorial=1, E=0.0001;
    for(k=0;k<=(n);k++){
                while(t<=n){
                        factorial*=t;
                        t++;
                }
                sum=(pow(-x,k))/factorial;
                sum+=sum;
                //while(fabs(sum-???)<E){
                //        result=sum;
                //}
    }

所以我知道序列的总和 sum(k)。但是要准确计算E,我必须知道之前元素的总和sum(k-1)。如何从 for 循环 中得到 sum(k-1)? 对不起英语。

【问题讨论】:

    标签: c++ c loops sequence precision


    【解决方案1】:

    这是 e ^ (-x) 的泰勒级数吗?如果是这样,你写错了。我不认为你所拥有的会收敛。

    http://www.efunda.com/math/taylor_series/exponential.cfm

    e ^ (-x) 是 1 + (-x) + (-x)^2/2! + (-x)^3/3! + ...

    double calculate_power_of_e(double xx, double accuracy) {
        double sum(1.0);
        double term(1.0);
        for (long kk=1; true; ++kk) {
            term *= (-xx) / kk;
            sum += term;
            if (fabs(term) < accuracy)
                break;
        }
    
        return sum;
    }
    
    printf("e^(-x)" = %.4f\n", calculate_power_of_e(5.0, .0001));
    

    【讨论】:

    • 哎呀。忘记更新 psum。只需在循环底部放一个 psum = sum。
    • 既然你有sum += term,你只需要检查fabs(term) &lt; accuracy。这使您可以摆脱第二个if (0 &lt; kk)。如果你在1 开始kksum,那么你也不需要先if (0 &lt; kk)。我为您修复了它,如果需要,请随时回滚编辑。
    • 看起来不错,谢谢。泰勒级数收敛缓慢。
    【解决方案2】:

    首先说明您应用的幂公式:根据wikipedia,您应该添加术语pow(-x,k)/(k!) 而不是pow(-x,k)/(n!)

    这会导致您的代码进行小幅优化:作为k! = k * (k-1)!,我们可以避免内部while 循环和大量无用的乘法。

    顺便说一句,你构建总和的方式也有一个错误:你总是删除以前的结果,然后第二次添加当前项。

    一旦这个问题得到纠正,你只需要处理一个额外的变量:

    double myexpo(double x, int n=100) {
        int k;
        double sum = 1.0, pvsum, factorial = 1.0, E = 0.0001;
        for (k = 1; k <= (n); k++){  // start with 1
            pvsum = sum;
            factorial *= k;            // don't calculate factorial for 0. 
            sum += (pow(-x, k)) / factorial;
    
            if (k > 1 && fabs(sum - pvsum) < E) {  // check if diff is small enough
                cout << k << " iterations" << endl; 
                break;     // interupt the for loop if it's precise enough
            }
        }
        return sum;   // at the end of the loop sum is the best approximation
    }
    

    你可以用这个来测试这个功能:

    double x; 
    do {
        cout << "Enter number: ";
        cin >> x;
        cout << myexpo(x) << endl; 
        cout << exp(-x) << endl; 
    } while (x > 0);
    

    备注:我建议使用 double 或使用 f 后缀作为浮点数(例如 0.001f),即使它按原样工作。

    【讨论】:

      【解决方案3】:

      检查项的绝对值何时小于您所需的准确度。

      double sum = 0, x = 1, k = 0, E = 0.0001, fact = 1;
      while(true){
          double term = pow(-x, k) / fact;
          if(fabs(term) < E)
              break;
          sum += term;
          fact *= (++k);
      }
      printf("e^(-x) = %.4f", sum);
      

      【讨论】:

        【解决方案4】:

        当术语与 1.0 相比微不足道时,停止循环。

        通过使用递归,|x|不太大,最小的项先求和。

        e(x) = 1 + x/1! + x*x/2! + x*x*x/3! + ...
        
        double my_exp_term(double x, double term, unsigned n) {
          if (term + 1.0 == 1.0) return term;
          n++;
          return term + my_exp_term(x, term*x/n, n);
        }
        
        double my_exp(double x) {
          return 1.0 + my_exp_term(x, x, 1);
        }
        
        double y = my_exp(-1);
        

        Exponential function

        【讨论】:

          猜你喜欢
          • 2021-01-24
          • 2021-02-03
          • 2010-10-24
          • 2018-02-19
          • 2014-05-28
          • 2017-04-04
          • 2014-03-27
          • 2014-11-25
          • 2019-07-28
          相关资源
          最近更新 更多