C ++:关于计算的精确度(代码在里面)

时间:2017-02-17 11:23:11

标签: c++ taylor-series

你能给我一些关于指数计算泰勒级数精度的建议吗?我们有指数度和精度数据作为输入数据计算。我们应该以给定的精度接收计算数作为输出数据。我写了一个程序,但是当我计算一个答案并将其与嵌入式函数的答案进行比较时,它就有了不同之处。你能告诉我,我怎么能破坏回答之间的区别? 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++;

    } 


}

1 个答案:

答案 0 :(得分: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以获取修改后的代码,该代码可让您使用已计算的结果继续系列以获得更高的精度。 Imho一个不错的解决方案也应该提供一种设置迭代次数限制的方法,但是我留给你实现;)