Szereg Maclaurina - program w C

0

Mam problem. A mianowicie napisałem program nr 3 z załącznika http://zapisz.net/view.php?filename=290_5.jpg . Może wiecie co jest nie tak. Proszę o pomoc.

#include <iostream> 
#include <conio.h> 
#include <math.h> 

int main() 

{ double x,k1,k2,a,b,c,d,e,suma1=0,suma2=0,suma3=0,suma4=0, suma5=0; 
int n,i,silnia=1,silnia1=1,silnia2=1; 
Czyzak: 
system("cls"); 
do 
{ 
printf("\n Podaj n="); 
k1=scanf("%d", &n); 
if (k1==0) printf("\n\t ERROR"); 
fflush(stdin); 
} 
while (k1==0||n<7); 

do 
{ 
printf("\n Podaj x="); 
k2=scanf("%lf", &x); 
if (k2==0) printf("\n\t ERROR"); 
fflush(stdin); 
} 
while (k2==0||fabs(x)>=1); 

for (i=0;i<=6;i++) 
{ 
if (i==0) {silnia==1;silnia1==1;silnia2==1;} 
else 
{ 
silnia=i*silnia; //n silnia 
silnia1=(2*i)*silnia1; // 2n silnia 
silnia2=(2*i+1)*silnia2; //2n+1 silnia 
} 

a=(pow(x,i))/silnia; 
b=(pow((-1),i))*((pow(x,(2*i+1)))/silnia2); 
c=(pow((-1),i))*((pow(x,(2*i)))/silnia1); 
d=(pow((-1),(i+1)))*((pow(x,i))/silnia); 
e=(pow((-1),i))*((pow(x,(2*i+1)))/(2*i+1)); 
suma1=suma1+a; 
suma2=suma2+b; 
suma3=suma3+c; 
suma4=suma4+d; 
suma5=suma5+e; 
printf("\n e^x=%lf",suma1); 
printf("\n sin x=%lf",suma2); 
printf("\n cos x=%lf",suma3); 
printf("\n ln (1+x)=%lf",suma4); 
printf("\n arctg x=%lf",suma5); 
} 

printf("\n\n WARTOSCI FUNKCJI Z BIBLIOTEKI MATH"); 
printf("\n e^x=%lf \n sin x=%lf \n cos x=%lf \n ln (1+x)=%lf \n arctg x=%lf",exp(x),sin(M_PI*x/180),cos(M_PI*x/180),log(x+1),atan(M_PI*x/180)); 
printf("\n\n"); 
getch(); 
goto Czyzak; 
system("PAUSE"); 
return 0; 
}
0

Co jest nie tak? Ano tylko jeden szczegół. Programowanie wymaga myślenia a nie bezmyślnego klepania. Co więcej wymaga też znajomości ELEMENTARNEJ matematyki. Wiesz co to jest szereg? Chyba nie, patrząc po tym kodzie.
Dla e^x rozwinięcie w szereg to nieskończona suma:
ex = 1+x+x2/2 + x3/6 + x4/12 + .... + x^n/n! + ....
Jak więc powinieneś to liczyć?
a0 = jakaś znana wartość
a1 = a0Q
a2 = a1
Q
i tak dalej.
Przykładowo dla e^x mamy
a0 = 1
a1 = a0x/1
a2 = a1
x/2
a3 = a2*x/3
i tak dalej. Więc wczytujesz od użytkownika liczbę N oraz X i na tej podstawie w pętli wyliczasz sobie wynik.

Ale wąpie żebyś coś z tego zrozumiał skoro nie wiesz co to szereg ani silnia...

0

A może ktoś wie jak to napisać poprawnie? Dopiero zaczynam programowanie i naprawdę topornie mi to idzie.

0

A cóż ci to da że ktoś umie to napisać? Na tym polega nauka że masz sam to zrozumieć i umieć napisać. Zapewniam cię, z czytania gotowego kodu NIE NAUCZYSZ się absolutnie niczego.

0

musze to oddac do jutra i mam kompletna pustke w glowie, bylbym wdzieczny gdybys mi z tym pomogl.

0

łomatko user image pierwszy raz widzę instrukcję goto w C++ do skoku. Chyba za dużo BASICA się naprogramowałeś w C-64. Programuj funkcyjnie - Twórz własne funkcje i używaj ich. Za samo użycie GOTO możesz mieć problemy, nigdy jej nie używaj, bo to nie jest zamysłem programowania obiektowego.

0

@pul4 jak masz to na jutro to znaczy że oblejesz. Ale nie martw sie , studia nie są dla kazego. Widać ze się na nich męczysz, a nie warto. Same studia bez umiejętności (których ewidentnie nie posiadasz) są guzik warte. No chyba że wykażesz się chojnością, powiedzmy 50zł za każdą funkcję którą program ma rozwijać w szereg.

dygresja: zadanie "napisz program rozwijający funkcje cos(x) w szereg Maclaurina" miałem na pierwszej kartkówce (czas na wykonanie zadania to ~15min) z programowania, na studiach"...

0
maszynaz napisał(a)

Programuj funkcyjnie - Twórz własne funkcje i używaj ich.

ROTFL, Ty tak na poważnie? :DDD Czyli że programowanie strukturalne to programowanie z użyciem struktur, logiczne z logicznym myśleniem (?) a dynamiczne to z przytupem? :D

maszynaz napisał(a)

Czyli Za samo użycie GOTO możesz mieć problemy, nigdy jej nie używaj, bo to nie jest zamysłem programowania obiektowego.

Paradygmaty programowania mają się nijak do struktur sterujących. Jak pan prezydent, w nadzieji i bulu oczekuję na poprawę.

0

w sumie to twoja próba jest jakąś tam interpretacją źle postawionego problemu
ja przyczepiłbym się do zadania 3.
to wyklawiaturowane "n" gdzie należy włożyć? "x" jest dane, ma być stałą czy tyże należy wprowadzić?
a porównać z wartością funkcji bibliotecznej jak?
błąd względny, bezwzględny, a może wystarczy różnica?
można tylko zgadywać o co chodziło
Jak znam życie to chodziło pewnie o to by dla "x" policzyć przybliżenie będące sumą "n" a może "2n+1" wyrazów rozwinięcia

tak może wyglądać sinus, sumuje n wyrazów rozwinięcia

double SIN(double x, int n){
        double a=x;
        double x2=x*x;
        double s=0;
        int i=1, k=0;
        while(k++<n) {
              s+= a;
              i+=2;
              a*= x2/(i-i*i);
        }
        return s;
}

Rozumiesz czemu tak?
Można to przećwiczyć np. tak:

const double PI=3.141592653589793238462643383;
 
int main(void) {
        int i;
        printf("    %0.15f wartosc dokladna\n", sin(PI/2));
        for(i=0; i<=10; i++)
                printf("%3d %0.15f\n", i, SIN(PI/2, i));
        return 0;
}
0

Program rozwija ci **e **w szereg McLaurena. Użyj np. x=2 i n<15 bo inaczej przekroczysz inta:

 
#include "stdafx.h"
#include <conio.h>
#include <math.h>

int ObliczSilnia(int n)
{
	int silnia=1;
	
	for(int i=2;i<=n;i++)
	{
		silnia=silnia*i;
	}

	return silnia;
}

double ObliczXdoN(int x, int n)
{
      
	return pow((double)x,(double)n);
}

double  ObliczSumeSzereguDla_n_Elementow(int x, int nliczba)
{
	double sum=0;
	for(int n=0;n<=nliczba;n++)
	{
		sum=sum+(ObliczXdoN(x,n)/(double)ObliczSilnia(n));
	}

	return sum;
}
//mainem sie nie przejmuj ja mam CPP w VS2010 wiec troche dziwne
int _tmain(int argc, _TCHAR* argv[])
{
int x=0;
int n=0;

printf("\n \nWczytuje liczbe x:"); 
scanf("%d", &x); 
printf("\nWczytuje liczbe n:");
scanf("%d", &n);

printf("\nSilnia x wynosi: %d",ObliczSilnia(n));

printf("\ne do x wynosi : %f",exp((double)x));
printf("\nrozwiniecie e do x w maclaurena wynosi: %f",ObliczSumeSzereguDla_n_Elementow(x,n));

getch();

	return 0;
}
0

Dzięki za pomoc :) a wiesz może jak ten program napisać w rozszerzeniu .c a nie .cpp ?

0

@maszynaz za to rozwiązanie na tej mojej rzeczonej kartkówce dostałbyś 0 punktów. Bo jest ekstremalnie nieoptymalne. Podałem w moim pierwszym poście jedyną poprawną metodę na liczenie tego...

0

powiedzmy, że chcemy policzyć e173, czyli exp(173), jest to coś około 1.35814259*1075
całkiem znośna liczba
ale, żeby uzyskać 1.358 E75 (4 poprawne cyfry) musimy zsumować ponad 200 wyrazów,
niestety ograniczone double nie pozwoli nam policzyć silni z niczego większego od (około) 170.
liczenie silni na int-ach przemilczę

double EXP(double x, int n){
        double s=0;
        double a=1;
        int i=0;
        while (i<n){
                s+=a;
                a=a*x/++i;
        }
        return s;
}
0

pul4 dostałeś już dzisiaj pałę za to zadanie czy się obroniłeś jakoś?

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