Forum MOJA PASJA - PROGRAMOWANIE Strona Główna
http://www.programuj.com
  WikiWiki  FAQFAQ    SzukajSzukaj    UżytkownicyUżytkownicy    GrupyGrupy   RejestracjaRejestracja 
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 




Obliczanie sin i cos bez funkcji bibliotecznych.


 
Napisz nowy temat   Odpowiedz do tematu    Forum MOJA PASJA - PROGRAMOWANIE Strona Główna -> C i C++
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
divii



Dołączył: 29 Gru 2006
Posty: 7

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Witam. Mam problem z pewnym zadaniem. Muszę napisać program obliczający sinus i cosinus z zadaną z góry dokładnością bez użycia funkcji bibliotecznych. Trzeba skorzystać przy tym z rozwinięcia w szereg Taylora.

Dla funkcji sinus szereg Taylora wygląda tak: sinx=x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - x^11/11! + ...
Funkcja, którą próbowałem do tego napisać wygląda tak:
c++:
double sinus (double x)
{
    double eps = 0.0000001;                //przybliżenie obliczeń
    double res=x;
    double ti=x;
    int i=2;
   
    while(ti>=eps)
    {
      ti=(ti*x*x)/(i++*i++);
      res-=ti;
      ti=(ti*x*x)/(i++*i++);
      res+=ti;
    }
    return res;
}

Coś tu jest źle, bo nie daje dobrego wyniku Confused. Mógłby mi ktoś pomóc w tym zadaniu?
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
molar
10100111001


Dołączył: 12 Sie 2006
Posty: 152

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
wydaje mi sie ze zle liczysz silnie bo w pierwszym przebiegu petli masz obliczyc 3! a wynik bedzie 4, a potem masz 5! a wynik to 4*4=16. tu jest prosta funkcja liczaca silnie rekurencyjnie
c++:

double silnia (int s)
{
double x;

if(s<0)
  printf("Podana liczba jest ujemna\n");
  x=0;
else if(s==0)
  x=1;
else
  x=s*silnia(s-1);

return x;
}
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość Wyślij email
divii



Dołączył: 29 Gru 2006
Posty: 7

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Moim zdaniem właśnie silnia jest liczona dobrze. Przecież w każdym przebiegu "i" jest zwiększane dwa razy, a poprzednia wartość nie jest usuwana. Nie jest najlepszym pomysłem jest tak znaczne zwiększanie złożoności obliczeń po przez wprowadzanie osobnej funkcji liczące silnie, na dodatek jeszcze w sposób rekurencyjny.

Nie wiem, w czym tutaj tkwi problem, ale w podobny sposób napisałem funkcję liczącą exponente (e^x) i ona działa dobrze. Tylko tutaj rozwinięcie jej w szereg Taylora jest trochę prostsze: exp(x)= 1 + x + x^2/2! + x^3/3! + x^4/4! + x^5/5! +... .

c++:

double exp (double x)
{
    double eps = 0.0000001;
    double res=1;
    int i=1;
    double ti=1;           
   
    while(ti>=eps)
    {
      ti=ti*x/i;
      res+=ti;
      i++;
    }
    return res;
}

Funkcja obliczająca sinus powinna być analogicznie zrobiona.
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
molar
10100111001


Dołączył: 12 Sie 2006
Posty: 152

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
silnia jest zle policzona. skompiluj sobie cos takiego i popatrz na wynik
c++:

//---------------------------------------------------------------------------

//#pragma hdrstop
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------

double sinus (double x)
{
    double eps = 0.000001;                //przybliżenie obliczeń
    double res=x;
    double ti=x;
    int j, i=2;


    while(ti>=eps)
    {
      j = (i++*i++);
      ti=(ti*x*x)/j;
      cout << j << endl;
      res-=ti;
      j = (i++*i++);
      ti=(ti*x*x)/j;
      cout << j << endl;
      res+=ti;
    }
    return res;
}


//#pragma argsused
int main(int argc, char* argv[])
{
  double z = sinus(1.3);
  cout << z;
  getchar();
  return 0;
}
//---------------------------------------------------------------------------

dzieje sie tak dlatego, ze zapis (i++*i++) jest realizownay w ten sposob, ze najpierw obliczany jest iloczyn, a potem nastepuje dwukrotna inkrementacja zmiennej i. a co do zlozonosci obliczeniowej to nie ma o czym mowic jezeli program ma tylko liczyc wartosc sin. chyba ze to ma byc czescia jakis bardziej zlozonych obliczen to mozesz wtedy to przerobic, tak zeby dzialalo szybciej
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość Wyślij email
divii



Dołączył: 29 Gru 2006
Posty: 7

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Program własnie nie może liczyć osobno silni. Napisałem już poprawną wersję, która prawdłowo oblicza wartość sin. Do funkcji podaje się wartość kąta podanego w stopniach.
c++:

double sinus (double x)
{
    double eps = 0.0000000001;                //przybliżenie obliczeń
    double pi = 3.1415926535;
    x=x*pi/180;                    //konwersja miary kąta ze stopni na radiany       
    double res=x;
    double ti=x;
    int i=0;
   
    while(ti>=eps)
    {
      i+=2;
      ti=ti*x*x/(i*(i+1));
      res-=ti;
     
      i+=2;
      ti=ti*x*x/(i*(i+1));
      res+=ti;
    }
    return res;
}
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
quetzalcoatl
programista


Dołączył: 30 Sty 2007
Posty: 531
Skąd: trójmiasto

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
divii - Twój pierwotny problem polegal na pomyleniu operatorow post- i pre- fixowych

Kod:

i=0;
...
i+=2;
ti=ti*x*x/(i*(i+1));     //2*3
i+=2;                        //i==4


jest tozsame nie z:
Kod:

int i=2;
...
ti=(ti*x*x)/(i++*i++);    //2*2, po linijce i==4


a z:

Kod:

i=1;
...
ti=(ti*x*x)/(++i*++i);   //2*3, po linijce i==4

_________________
Tadeusz Pys
jestem wyrozumialy, ale zanim zadasz pytanie przeczytaj:
http://rtfm.killfile.pl/
http://www.wsp.krakow.pl/papers/f_lamer.html
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
Przemo.bundy



Dołączył: 11 Maj 2016
Posty: 3

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Witam.
Wiem ze ten post jest stary.
Ale sprawdzilem ten kod programu i dziala.
Czy moze ktos mi podpowiedziec jak ten program przerobic tak
Zeby obliczal cosinus. Bede wdzieczny.
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
Albert Rosenfield
programista


Dołączył: 26 Kwi 2007
Posty: 2418
Skąd: olsztyn

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Ktoś tu chyba na matematyce nie był uważny -> cosinus(x) => sinus(x + pi/2).
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
izaw
programista


Dołączył: 17 Cze 2008
Posty: 1608
Skąd: Łódź

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
To też. Ale głównie leń i wyłudzacz kodów.
_________________
"Nic nie jest tak proste, by nie można było wykonać tego źle"
Prawo Murph'ego
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
Przemo.bundy



Dołączył: 11 Maj 2016
Posty: 3

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Izaw mowisz o sobie. Bo twoja odpowiedz nie ma nic wspolnego z pytaniem. Nabijasz puste posty.
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
izaw
programista


Dołączył: 17 Cze 2008
Posty: 1608
Skąd: Łódź

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
No to pokaż kod.
_________________
"Nic nie jest tak proste, by nie można było wykonać tego źle"
Prawo Murph'ego
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
Przemo.bundy



Dołączył: 11 Maj 2016
Posty: 3

Post Zacytuj zaznaczone Odpowiedz z cytatem OCEŃ POST
Dzieki Albert za pomoc. Z uwagi ze program napisalem w basic! Android przystosowalem go do niego. Poprostu chcialem narysowac kolo bez funkcji bibliotecznych.no a docelowo chce zrobic program w asemblerze.
Powrót do góry
Ogląda profil użytkownika Wyślij prywatną wiadomość
Wyświetl posty z ostatnich:   
Napisz nowy temat   Odpowiedz do tematu    Forum MOJA PASJA - PROGRAMOWANIE Strona Główna -> C i C++ Wszystkie czasy w strefie CET (Europa)
Strona 1 z 1

 
Skocz do:  
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach


hosting sponsorowany przez hosted.pl
Powered by phpBB © 2001, 2002 phpBB Group