Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[c++]Szereg Taylora - cosinus

Ostatnio zmodyfikowano 2014-09-23 14:33
Autor Wiadomość
FreeFeynman123
Temat założony przez niniejszego użytkownika
[c++]Szereg Taylora - cosinus
» 2014-03-22 19:27:37
Witam!
Napisałem następujący program, który ma na celu obliczać wartość cosinusa z rozwinięcia w szereg Taylora:
C/C++
#include <iostream>
#include <cmath>
using namespace std;
double fac( int n )
{
    double f = n;
    while( --n ) f *= n;
   
    return f;
}
int main()
{
    double long x;
    cout << "Kat w radianach: " << endl;
    cin >> x;
    double cos( 1.0 );
    double temp( 0.0 );
    for( int i = 0; i < 170; i++ ) {
        if( i % 2 == 1 )
             temp =( pow( x, i * 2 + 2 ) ) /( fac( i * 2 + 2 ) );
        else
             temp =( - 1 ) *( pow( x, i * 2 + 2 ) ) /( fac( i * 2 + 2 ) );
       
        if( fabs( temp ) <= 0.0001 )
             break;
        else
             cos += temp;
       
    }
    cout << "Wartosc cosinusa wynosi: " << cos << endl;
    return 0;
}

Działa on dla wartości do około 35, kiedy wpiszę np. 40, to zaczyna zwracać zupełnie bezsensowne wyniki. Czy ktoś ma jakiś pomysł z czego to wynika?
Z góry dziękuję za pomoc i pozdrawiam.
P-107024
pekfos
» 2014-03-22 20:04:50
Zapewne wyniki potęgowania/silni są zbyt duże.
P-107026
FreeFeynman123
Temat założony przez niniejszego użytkownika
» 2014-03-22 22:37:11
Domyślam się, zastanawia mnie tylko dlaczego taka formuła jest zła? W zasadzie ten kod spełnia wszystkie własności, które powinno mieć te rozwinięcie.
P-107037
pekfos
» 2014-03-23 14:21:22
Formuła matematycznie może i jest dobra, ale nie informatycznie. Typy danych mają ograniczenia, które musisz spełniać na każdym etapie obliczeń. Możesz użyć bibliotek do dużych liczb, ale w tym przypadku to nie ma większego sensu, bo można to załatwić dużo prościej.
P-107075
docentpp
» 2014-03-23 15:16:42
Można prościej :

C/C++
long double cos_t( long double x, int n )
{
    long double
    wynik = 0.0,
    licznik = 1.0,
    mianownik = 1.0;
    for( int i = 0; i < 2 * n; i += 2 )
    {
        wynik += licznik / mianownik;
        licznik *=( - 1 ) * x * x;
        mianownik *=( i + 1 ) *( i + 2 );
    }
    return wynik;
}

P-107085
Anim
» 2014-09-23 13:30:34
hej, chciałbym to odświeżyć. Robię podobne zadanie, tylko, że dla sinusa, a to znaczy, że mianownik wzrasta 1!, 3!, 5!... i moje pytanie jest bardziej matematyczne, niźli informatyczne...przyjemna jest ta konwencja dla cosinusa (i+1)(i+2), dla i+=2... Macie jakiś pomysł dla sinusa ?
P-117386
pekfos
» 2014-09-23 14:33:32
(i+2)(i+3) i inny licznik.
P-117387
« 1 »
  Strona 1 z 1