Funkcja licząca sinusa

0

Dzień dobry.
Chcę napisać funkcję liczącą przybliżenie sinusa za pomocą wzoru Taylora z zadaną dokładnością. Napisałem na razie coś takiego:

double sinus(double x)
{
    double wynik=0;
    double y=x;
    double z=2;
    
    for(int n=0; n<10; n++)
    {
        wynik+=y;
        y*=-1;
        y*=x;
        y*=x;
        y=y/(z++);
        y=y/(z++);
    }
    
    return wynik;
}

i mam dwa pytania: czy da się jakoś "ładniej" zapisać środek pętli tzn. aby tyle nie mnożyć i dzielić,
a drugie to jak ustawić zadać dokładność liczenia? Nie umiałem tego zrobić stąd pętla for na 10 powtórzeń.

0

Tak, wynik jest dobry. Zgadza się z tym co w wolframie po 3-4 powtórzeniach pętli

0

Tu https://4programmers.net/Forum/C_i_C++/321157-wzor_maclaurina_dla_sin?p=1558555#id1558555 jest rozwinięcie w szereg MacLaurina. Dokładność zależna od ilości iteracji. A jak ocenić dokładność absolutną, sam chciałbym wiedzieć!

0

Dziękuję za odpowiedź jednak nie mogę w swoim rozwiązaniu użyć żadnej funkcji bibliotecznej, a algorytm nie może liczyć silni...

0

To nie wiem, bo w rozwinięciu w szereg Taylora/MacLaurina jest silnia, poza tym nie używam funkcji bibliotecznych.

0

W tym przypadku wydaje mi się, że jedyne co możesz zrobić to:

double sinus( double x )
{
    double wynik = 0;
    double y = x;
    double z = 2;
 
    for ( int n = 0; n < 10; ++n )
    {
        wynik += y;
        y *= -x * x;
        y = y / ( z++ );
        y = y / ( z++ );
    }
 
    return wynik;
}

Co do drugiego pytania to możesz przesłać w drugim parametrze (który jest ustawiony domyślnie na 10) tę precyzję, o tak:

double sinus( double x, int precision = 10 )
// ...
    for ( int n = 0; n < precision; ++n ) // tutaj nie jestem pewien, czy precyzja zależy od liczby iteracji - możliwe, że nie.

Cały kod z trzema testami: https://ideone.com/OW78Ci

0

Liczenie przy rozwinięciu w szereg z zadaną dokładnością eps odbywa się w ten sposób, że kończymy obliczanie w przypadku, gdy moduł n-tego element rozwinięcia jest mniejszy od naszego zadanego eps. Nic trudnego. W pseudokodzie będzie to coś takiego:

double sinus(double x, double eps)
{
  int i;
  double temp,value;

  value = x;  // wynik zwracany
  i = 1;    // licznik petli
  temp = x; // i-ty element szeregu, w pierwszym przylizeniu to po prostu x
 
  while (fabs(temp) > eps)
  {
    temp = ....; // tu obliczamy sobie i-ty element szeregu
    value = value + temp;
    ++i;
  }
  return value;
}

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