Suma szeregu .

0

Hello! Czy ten kod dobrze odzwierciedla szereg ( https://prnt.sc/rksfrw) , jak widzicie jakiś błąd - zgłoście :
screenshot-20200322220132.png

double szereg(double x, double delta, int* z)
{
	x = -x;
	double y = 1, d = 1, licznik = 1, mianownik = 4;
	int i = 1;
	while (fabs(d) >= delta)
	{
		if (i == *z) break;
		d *= licznik / mianownik * x;
		y += d;
		licznik += 4;
		mianownik += 4;
		i++;
	}
	*z = i;
	return y;
}  ```
0

Co oznacza ± w tym szeregu?

1
Pablo1999 napisał(a):

Hello! Czy ten kod dobrze odzwierciedla szereg ...

Policz na kartce kilka pierwszych wyrazów podanego szeregu i porównaj z wynikami programu. Będziesz wiedział bez pytania innych. (Tak. Są błędy. Gubisz się w znakach i licznik za szybko rośnie.)

0

Jakoś tak :


#include <stdio.h>
#include <math.h>

int main()
    
{double x;
double c=2;
double *z;
z = &c;
    scanf("%lf",&x);
    
    double y = 1, d = 1, licznik = 1, mianownik = 4;
    int i = 1;
    *z = 2;
    while (x)
    {
        if (i == *z) break;
        if (licznik <= 3) {d *= licznik / mianownik * x;
        y += d;
        licznik += 2;
        mianownik += 2;
        i++;
        }
        else {
        d *= licznik / mianownik * x;
        y += d;
        licznik += 4;
        mianownik += 4;
        i++;}
        
    }
    *z = i;
    x = -x;
    printf("%lf" ,y);
    return 0;
}
1

Wydaje mi się, że ten szereg dla pewnych dużych x, może być rozbieżny; nie wiem, ale z tego by wynikało, że nie można obliczać wyniku z pewną dokładnością (kolejne wyrazy moga być coraz większe). Lepiej, dać funkcję z ograniczoną ilością iteracji:

int my_sign(int i) {
	if (i % 2 == 0) return 1;
	return -1;
}

double series(double x, int n) {
	if (n == 1) return 1.0;
	if (n == 2) return 1.0 + (1 * x) / 4;
	if (n == 3) return 1.0 + (1 * x) / 4 + (3 * x * x) / 32;
	double num = 3;
	double den = 8;
	double s = 1.34375;
	double x1 = x * x;
	for (int i = 4, s_num = 7, s_den = 12; i <= n; ++i, s_num += 4, s_den += 4) {
		num *= s_num;
		den *= s_den;
		s += (my_sign(i) * ((num / (4.0 * den)) * x1 * x));
		x1 *= x;
	}
	return s;
}

Trzy pierwsze elementy są zwracane "ifami", bo są nieregularne, żeby pętla była mentalnie do ogarnięcia.

EDYCJA: Zedytowałem kod, jest poprawne akumulowanie faktorów w liczniku i mianowniku, oraz potęgowanie x - a.

0
std::pair<double, int> f(double x, double epsilon, int max_n)
{
    double ai = x / 4;
    double sum = 1 + x / 4;
    int i = 1;
    while (i < max_n && std::abs(ai) > epsilon) {
        ai = -ai * (4 * i - 1) / (4 * i + 4);
        sum += ai;
        ++i;
    }
    return std::make_pair(sum, n);
}
0

@MarekR22: To miało być w C ;P. Ale:

double f(double x, int max_n){
    double ai = x / 4;
    double sum = 1 + x / 4;
    int i = 1;
    while (i < max_n) {
        ai = -ai * (4 * i - 1) / (4 * i + 4);
        sum += ai;
        ++i;
    }
    return sum;
}

Dla f(2.0, 5) - czyli jak rozumiem, sumujemy 5 perwszych elementów szeregu, daje zły wynik, powinno być 1.179688, sprawdzałem ręcznie.

0

Z moich testów dla x=1 (łatwiej liczyć) wychodzi poprawnie
demo

Ok zapominałem o czynniku x :)

std::pair<double, int> f(double x, double epsilon, int max_n)
{
    double ai = 1;
    double sum = 1;
    int i = 0;
    while (i <= max_n && std::abs(ai) > epsilon) {
        ai = -ai * x * (4 * i - 1) / (4 * i + 4);
        sum += ai;
        ++i;
    }
    return std::make_pair(sum, i);
}

demo

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