Bład przy liczeniu niektórych wartości - szereg Taylor'a

0

Witam!

  Poniższy program ma liczyć wartości funkcji e^x za pomocą szeregu Taylor'a, porównać z wartością dokładna, którą dostajemy za pomocą funkcji expl() ze standardowej biblioteki <math.h>  i wyliczyć błąd względny dla x z przedziału [-30,30]. Generalnie program liczy całkiem poprawnie dla wartości x z przedziału [-20 , 30], jednak dla reszty zaczyna wyrzucać błędne wartości, które nie zgadzają się z dokładnymi nawet o kilka rzędów wielkości. Ma ktoś jakiś pomysł co jest nie tak i co z tym można zrobić? 

Z góry dzięki za pomoc.

 
#include<iostream>
#include<math.h>

using namespace std;

long double szereg_taylora_ex(long double dokladnosc,long double potega)
{
    long double wp,kolejny = 1.0;
    long double i;
    long double p = potega;

    for(i = 0.0; i <= dokladnosc ; i += 1.0)
        {
            if(i == 0.0) wp = 1.0;
            else {
                    kolejny *= p/i;
                    wp += kolejny;
                 }
        }
    return wp;

}

int main()
{
    long double wp,wd,rel;
    long double i;

    cout.width(5);
    cout << "x |";
    cout.width(17);
    cout << "wd |";
    cout.width(17);
    cout << "wp |";
    cout.width(17);
    cout << "rel |" << endl;
    cout << "--------------------------------------------------------" << endl;
    for(i = -30.0 ;i <= 30.0 ; i += 1.0)
    {
        wd = expl(i);
        wp = szereg_taylora_ex(100.0,i);

        cout.width(4);
        cout << i << "|";
        cout.width(16);
        cout << wd << "|";
        cout.width(16);
        cout << wp << "|";
        cout.width(16);
        rel = (wp-wd)/wd;
        if(rel >= 0.0)
            cout << rel << "|" << endl;
        else
            cout << -rel << "|" << endl;
    }
    return 0;
}

0
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;
 }

http://stackoverflow.com/questions/26142839/using-fractional-base-when-summing-taylor-series-causes-infinite-loop

0

Ogólna uwaga - licznik i typu zmiennoprzecinkowego może zadziwić, jeśli wpadnie w duże wartości to po dodaniu 1 może się okazać, że wartość się nie zmieni, więc nie używać, jeśli nie jesteśmy pewni, że taka sytuacja nie nastąpi!

0

Totalne bzdury...

ex = 2(x loge);

gdzie: loge = log_2 e = lne/ln2 = 1/ln2

1 użytkowników online, w tym zalogowanych: 0, gości: 1