Funkcja licząca sin(x) wzorem Taylora - problem z silnią

0

Witam. Mam do zaprogramowania funkcję liczącą sin x wzorem Taylora. Problem mam z mianownikiem (2n+1)! . Nie mam problemu z zaimplementowaniem zwykłej silni ( liczącej po kolei 1!, 2!, 3!, 4! itd.), ale kiedy przychodzi do tego, że muszę obliczyć 3! bez wcześniejszego obliczania 2!, to nie wiem jak się do tego zabrać.. Moja funkcja programisty:

void m_sin(double x)
{
	int N = 10;
	long long silnia;

	for (int i = 0; i < N; i++)
	{
		int licznik, mnozenie,mianownik_bez_silni;

		licznik = pow(-1, i);
		mnozenie = pow(x, (2 * i + 1));
		mianownik_bez_silni = 2 * i + 1;
		printf("i=%d,mianownik=%d", i, mianownik_bez_silni);
	}
}

pS. link do wzoru : https://zapodaj.net/ddff330eb6df9.png.html
W zadaniu powiedziano, aby wykonać 10 iteracji(dlatego N=10)

1

Nie da się, bo n! to 1 * 2 * ... * n - 1 * n:

long fact(long n) {
	long s = 1;
	for (long i = 1; i <=n; ++i)
		s *= i;
	return s;
}
1

Zwróć uwagę, że przy kolejnych składnikach sumy nie musisz wyliczać silni od początku, tylko możesz skitrać gdzieś wynik cząstkowy z poprzedniego składnika.

Np. jeśli masz policzone (2n + 1)! dla n=5, czyli 11!, to w następnej iteracji, gdy masz policzyć dla n=6 (czyli 13!), nie musisz liczyć od początku: 1 * 2 ...* 13, tylko 11! * 12 * 13. Pozwoli ci to zrobić wydajniejszy program.

1

Od siebie dodam, że możesz być sprytny i zrobić sobie taką tablicę

constexpr auto facts = std::array{
    1ull,
    1ull,
    2ull,
    6ull,
    24ull,
    120ull,
    ...
    2432902008176640000ull
};

Dojechałem do 20! bo to jest max jaki mieści się na 64 bitach bez znaku (jak masz unsigned long long większy niż 64 bity, to sobie odpowiednio powiększ tablicę).

Teraz, obliczenie n! wygląda tak: facts[n].

2

Ludzie litość napisał: Mam do zaprogramowania funkcję liczącą sin x wzorem Taylora.
Czy nie powinien liczyć jawnie silni! Po prostu na float/double ma liczyć kolejne elementy szeregu Taylora!
Kolejne elementy sumy ma liczyć przez mnożenie poprzedniego elementu sumy o odpowiedni czynnik.

double taylor_sin(double x, double epsilon)
{
     double ai = x;
     double sum = ai;
     int i = 1;
     while (std::abs(ai) > epsilon) {
          ai *= wyrazenie_zalezne_od(++i, x);
          sum += ai;
     }
     return sum;
}

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