【问题标题】:C++: about precision of calculating (code is inside)C++:关于计算精度(代码在里面)
【发布时间】:2017-07-06 21:44:31
【问题描述】:

你能给我关于计算指数泰勒级数精度的建议吗?我们有一个指数和一个精度计算的数字作为输入数据。我们应该收到一个具有给定精度的计算数字作为输出数据。我写了一个程序,但是当我计算一个答案并将其与嵌入式函数的答案进行比较时,它有不同之处。你能告诉我,我怎样才能消除答案之间的差异? formula of exponent's calculating

#include "stdafx.h"
#include "iostream"
#include <math.h>
#include <Windows.h>
#include <stdlib.h>

using namespace std;

int Factorial(int n);
double Taylor(double x, int q);
int main()
{
    double res = 0;
    int q = 0;
    double number = 0;
    cout << "Enter positive number" << "\n";
    cin >> number;
    cout << "Enter rounding error (precision)" << "\n";
    cin >> q;
    cout << "\n" << "\n";
    res = Taylor(number, q);
    cout << "Answer by Taylor : " << res;
    cout << "Answer by embedded function: " << exp(number);
    Sleep(25000);

    return 0;
}

int Factorial(int n) {              
    int res = 1;
    int i = 2;
    if (n == 1 || n == 0)
        return 1;
    else
    {
        while (i <= n)
        {
            res *= i;
            i++;
        }
        return res;
    }
}

double Taylor(double x, int q) {
    double res = 1;
    double res1 = 0;
    int i =1;
    while (i)
    {
        res += (pow(x, i) / Factorial(i));
        if (int(res*pow(10, q)) < (res*pow(10, q)))
        {//rounding res below
            if ( ( int (res * pow(10,q+1)) - int(res*pow(10, q))) <5 )
                res1 = (int(res*pow(10, q))) * pow(10, (-q));
            else
                res1 = (int(res*pow(10, q))) * pow(10, (-q)) + pow(10,-q);

            return res1;

        }

        i++;

    } 


}

【问题讨论】:

  • 有什么区别?您尝试扩展什么功能?
  • 我想让泰勒函数像嵌入函数一样更准确。例如,您可以尝试输入变量,您会看到答案有所不同。
  • 你得到了什么结果,它们与你想要得到的结果有何不同?
  • @tryuf 至少,在询问之前修复所有警告,因为它们可能是您的问题的原因:warning C4715: 'Taylor' : not all control paths return a value
  • 如果一个结果是 39,334,另一个是 148,413,那么这很可能不是精确问题,但更有可能是您的结果完全错误

标签: c++ taylor-series


【解决方案1】:

您的代码中有两个问题。首先,阶乘很容易溢出。实际上我不知道int 阶乘何时发生溢出,但我记得例如在通常的袖珍计算器上x! 已经溢出x==70。您可能不需要那么高的阶乘,但最好从一开始就避免这个问题。如果您查看需要在每个步骤中添加的更正:x^i / i!(数学符号),那么您会注意到该值实际上分别比x^ii! 小得多。您也可以通过简单地将前一个值乘以x/i 轻松计算该值。

第二,我不明白你的精度计算。也许它是正确的,但老实说,它看起来太复杂了,甚至无法理解它;)。

以下是获取正确值的方法:

#include <iostream>
#include <cmath>

struct taylor_result {
        int iterations;
        double value;
        taylor_result() : iterations(0),value(0) {}
};

taylor_result taylor(double x,double eps = 1e-8){
    taylor_result res;
    double accu = 1;                           // calculate only the correction
                                               // but not its individual terms
    while(accu > eps){                        
         res.value += accu;
         res.iterations++;
         accu *= (x / (res.iterations));
    }
    return res;
}       

int main() {
    std::cout << taylor(3.0).value << "\n";
    std::cout << exp(3.0) << "\n";
}

请注意,我使用了一个结构来返回结果,因为您应该注意所需的迭代次数。

PS:请参阅 here 以获取修改后的代码,该代码可让您使用已计算的结果来继续该系列以获得更高的精度。恕我直言,一个不错的解决方案还应该提供一种设置迭代次数限制的方法,但我留给您实施;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多