 |
Budownictwo 2006 Wydział Inżynierii Lądowej Politechniki Krakowskiej
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Itea
Operator Łopaty
Dołączył: 28 Sty 2007
Posty: 18
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Okolice Miechowa
|
Wysłany: Pią 15:57, 11 Maj 2007 Temat postu: czy mógłby ktoś znaleźć błąd w tym programie? |
|
|
wiem, że pytanie jest absurdalne, ale ten program to już jakieś 10 godzin wyjęte z życiorysu. może komuś z was nudzi się do tego stopnia, że poszuka błędu ;]
na początek, dla porównania, program, który działa dobrze:
mamy funkcje w postaci sumy szeregu exp(x)=1+ x/1!+ x^2/2!+ x^3/3!+....
musimy napisać program który wylicza i wypisuje w kolumnach :
x należące do przedziału wybranego przez użytkownika;
f(x)będące sumą pewnej ilości początkowych wyrazów, oraz
fd(x) które jest dokładna wartością funkcji dla zmiennej x i jest po prostu wynikiem podstawienia x do wzoru exp(x).
ważne jest, żeby f(x) było jak najbliższe fd(x)
Użytkownik podaje z klawiatury początek przedziału, koniec przedziału, krok i dokładność. trzeba użyć funkcji zwracającej sumę szeregu, w tej funkcji ma być pętla do..while. w funkcji main ma być pętla for dzięki której wypiszemy w kolumnach wyniki.
To co na początku musimy zrobić, znając wzór funkcji, to okreslić 1 wyraz:a0 i ustalić zależność miedzy a(n) i a(n+1). dla naszej funkcji mamy:
a0=1
a(n+1)=a(n)*x/(n+1)
ważna rzecz to wiedzieć, co to jest kryterium stopu, i zwłaszcza, do czego służy.
jest potrzebne do tego, żeby nasz program wiedział, kiedy przestać dodawać początkowe wyrazy szeregu i zwrócić ich sumę. ma przestać dodawać, kiedy :
wartość bezwzględna z pewnego a(n) okaże się mniejsza od eps*(suma n początkowych wyrazów szeregu).
eps nazywamy dokładnością, to jakaś mała stała, np:0.001.
==========
po tym przydługim wstępie, wreszcie program.
==========
#include <stdio.h>
#include <math.h>
#include<stdlib.h>
int main()
{
double x,x0,xk,dx,eps,y;
double fun(double x,double eps);
printf("podaj wartosc poczatkowa, koncowa, krok i dokladnosc\n");
scanf(" %lf %lf %lf %lf",&x0,&xk,&dx,&eps);
for(x=x0;x<=xk;x=x+dx)
{
y=fun(x,eps);
printf("x=%lf f(x)=%lf fd(x)=%lf\n",x,y,exp(x));
}
system("pause");
return 0;
}
double fun(double x,double eps)
{
double s, a;
long n;
s=0;
n=0;
a=1;
do
{
s=s+a;
n=n+1;
a=double((a*x)/n);
}
while(fabs(a) > eps*fabs(s));
return s;
}
===========================
no, a teraz program,który miał działać w ten sam sposób, a który z niezrozumiałych dla mnie względów nie działa dobrze.
tym razem funkcja jest dana wzorem
(1+x)^ -1/3=1-1/3*x + (1/3*4/6)*x^2 - (1*4*7/3*6*9)*x^3 + (1*4*7*10/3*6*9*12)*x^4 -......
===========================
#include <stdio.h>
#include <math.h>
#include<stdlib.h>
int main()
{
double x,x0,xk,dx,eps,y;
double fun(double x,double eps);
printf("podaj wartosc poczatkowa, koncowa, krok i dokladnosc\n");
scanf(" %lf %lf %lf %lf",&x0,&xk,&dx,&eps);
for(x=x0;x<=xk;x=x+dx)
{
y=fun(x,eps);
printf("x=%lf f(x)=%lf fd(x)=%lf\n",x,y,pow((1+x),-0.3333));
}
system("pause");
return 0;
}
double fun(double x,double eps)
{
double s,a;
long m,l;
m=3;
l=1;
a=1;
s=1;
do
{
a=double(a*(-x)*l/m);
m=m+3;
l=l+3;
s=s+a;
}
while(fabs(a)>eps*fabs(s));
return s;
}
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Lord Def
Kierowca Wywrotki
Dołączył: 23 Paź 2006
Posty: 92
Przeczytał: 0 tematów
Pomógł: 2 razy Ostrzeżeń: 0/5
|
Wysłany: Sob 11:56, 12 Maj 2007 Temat postu: |
|
|
Itea napisał: |
ważna rzecz to wiedzieć, co to jest kryterium stopu
|
No właśnie.
Stosujesz szereg Maclaurina i pomijaz reszte Lagrange'a. Jak się okazuje zmierza ona do nieskączoności dla ksi należącego (0,1) i x>1. Napisany przez ciebie szereg jest prawidłowy, ale rozbieżny dla x>1. Tzn. a i s "zmieżają" do +/- inf, a pętla zostaje zakończon gdy znaki odpowiednio się różnią.
Zastosuj szereg Taylora i odpowiednio zwiększaj x_0 zależnie od przedziału. Im różnica x_0 i x większa tym większ dokładność, ale |x_0-x|<x_0+1 aby szereg był zbieżny.
Rownież kolejność wykonywanych działań ma znaczenie, jeśli o dokładność chodzi, ale teraz nie chce Mi się nad tym myśleć.
W warunku pętli stosujesz dokładność względną, sprawdzałem to troche i w tym przypadku nie ma różnicy, ale mniejsza z tym.
I jeszcze jedno, szereg z którym porównujesz wyniki jest niedokładny, -0.3333 to troszkę za mało jak na -1/3 Spróbuj dodać stała -1.0/3.0.
Powodzenia.
WoW mam 2/3 Lucka
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Itea
Operator Łopaty
Dołączył: 28 Sty 2007
Posty: 18
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Okolice Miechowa
|
Wysłany: Sob 17:33, 12 Maj 2007 Temat postu: |
|
|
Dzięki za pomoc!
wiem już, co nie gra. Nie wiem, czy jest sens pisać nowe rozwinięcie w szereg Taylora uwzględniające tę resztę, skoro w zadaniu mieliśmy podane właśnie takie rozwinięcie jak napisałam.. W zasadzie i tak nie mam pojęcia, jak to:
odpowiednio zwiększaj x_0 zależnie od przedziału. Im różnica x_0 i x większa tym większ dokładność, ale |x_0-x|<x_0+1 aby szereg był zbieżny.
uwzględnić w programie...
Mąm nadzieję, że wystarczy jak oddam ten program z poprawką:stała -1.0/3.0. i komentarzem, że dla podanego rozwinięcia działa jak powinien;]
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Lord Def
Kierowca Wywrotki
Dołączył: 23 Paź 2006
Posty: 92
Przeczytał: 0 tematów
Pomógł: 2 razy Ostrzeżeń: 0/5
|
Wysłany: Sob 18:56, 12 Maj 2007 Temat postu: |
|
|
Dla x_0=63 wygląda to tak:
Kod: |
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double fun(double x,double eps)
{
double s,a;
double m,l;
m=3;
l=1;
a=0.25;
s=0.25;
x=x-63; /* dla x_0=63 mozna obliczac szereg od 0 do 127
dla x_0=124 od 0 do 249 itd.
mozna ustalac w zaleznosci od przedzialu w jakim jest x */
do
{
a*=-(l*x)/(m*64);
m+=3;
l+=3;
s+=a;
}
while(fabs(a)>eps*fabs(s));
return s;
}
int main()
{
int n,i;
double x,x0,xk,dx,eps,y,p;
printf("podaj wartosc poczatkowa, koncowa, krok i dokladnosc\n");
scanf(" %lf %lf %lf %lf",&x0,&xk,&dx,&eps);
n=(int)((xk-x0)/dx)+1;
p=-1.0/3.0;
for(i=0;i<n;i++)
{
x=x0+(double)i*dx;
y=fun(x,eps);
printf("x=%lf f(x)=%lf fd(x)=%lf\n",x,y,pow((1+x),p));
}
scanf("%*2c");
return 0;
}
|
No tak, twój program działa poprawnie, tzn. tak jak jest napisane w zadaniu.
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Itea
Operator Łopaty
Dołączył: 28 Sty 2007
Posty: 18
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Okolice Miechowa
|
Wysłany: Nie 17:45, 13 Maj 2007 Temat postu: |
|
|
No, teraz wszystko już jasne. nie sadziłam, że są ludzie, którzy lubią się w to bawić, a jednak ;]. Jeszcze raz wielkie dzięki![/b]
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Itea
Operator Łopaty
Dołączył: 28 Sty 2007
Posty: 18
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Okolice Miechowa
|
Wysłany: Nie 18:48, 13 Maj 2007 Temat postu: |
|
|
no, teraz działa już dla dowolnego przedziału. może komuś się przyda na coś:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double fun(double x,double eps,double xk, double x00)
{
double s,a;
double m,l;
x00=(xk/2)+1;
m=3;
l=1;
a=pow(x00,-1.0/3.0);
s=pow(x00,-1.0/3.0);
x=x-x00;
do
{
a*=-(l*x)/(m*(x00+1));
m+=3;
l+=3;
s+=a;
}
while(fabs(a)>eps*fabs(s));
return s;
}
int main()
{
int n,i;
double x,x0,xk,dx,eps,y,p,x00;
printf("program rozwija funkcje(x+1)^-1/3 w szereg potegowy. stosuje rozwiniecie Taylora\n");
printf("podaj wartosc poczatkowa, koncowa, krok i dokladnosc\n");
scanf(" %lf %lf %lf %lf",&x0,&xk,&dx,&eps);
x00=(xk/2)+1;
printf("punkt wzgledem ktorego rozwijamy szereg to x00=%lf\n\n",x00);
n=(int)((xk-x0)/dx)+1;
p=-1.0/3.0;
for(i=0;i<n;i++)
{
x=x0+(double)i*dx;
y=fun(x,eps,xk,x00);
printf("x=%lf f(x)=%lf fd(x)=%lf\n",x,y,pow((1+x),p));
}
system("pause");
return 0;
}
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
klemens
Majster
Dołączył: 09 Gru 2006
Posty: 122
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Kingston PL
|
Wysłany: Pon 20:15, 14 Maj 2007 Temat postu: |
|
|
system("pause");
wytłumaczy mi ktoś co to robi? bo jakoś nie zauważyłem żeby ta linijka coś dawała . . .
Ale ja leon z poczty jestem
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pepe
Rajdowiec :D
Dołączył: 27 Paź 2006
Posty: 409
Przeczytał: 0 tematów
Pomógł: 1 raz Ostrzeżeń: 0/5 Skąd: gród Kraka
|
Wysłany: Pon 22:49, 14 Maj 2007 Temat postu: |
|
|
ta komenda jest potrzebna w sumie tylko jak programujesz pod DEV C++
Jezeli jej nie zastosujesz to ci sie po prostu program nie wlaczy
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Dobry
Prezes
Dołączył: 16 Paź 2006
Posty: 1273
Przeczytał: 0 tematów
Pomógł: 13 razy Ostrzeżeń: 0/5 Skąd: Festung Krakau
|
Wysłany: Pon 23:01, 14 Maj 2007 Temat postu: |
|
|
Ja wolę zamiast system pause dawać tak:
na górze: #include <conio.h>
i na końcu maina: getch();
daje to dokładnie ten sam efekt...
Tylko nie pamiętam, czy to nie jest już C++, czy samo C...
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Piotrek
Kierownik Budowy
Dołączył: 28 Paź 2006
Posty: 285
Przeczytał: 0 tematów
Pomógł: 2 razy Ostrzeżeń: 0/5 Skąd: Tarnowskie Góry - KRK
|
Wysłany: Pon 23:47, 14 Maj 2007 Temat postu: |
|
|
scanf tez moze byc
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Dobry
Prezes
Dołączył: 16 Paź 2006
Posty: 1273
Przeczytał: 0 tematów
Pomógł: 13 razy Ostrzeżeń: 0/5 Skąd: Festung Krakau
|
Wysłany: Wto 15:56, 15 Maj 2007 Temat postu: |
|
|
Lub cin << a; przy bibliotece #include <iostream.h>.
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
klemens
Majster
Dołączył: 09 Gru 2006
Posty: 122
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Kingston PL
|
Wysłany: Wto 19:02, 15 Maj 2007 Temat postu: |
|
|
Pepe napisał: | ta komenda jest potrzebna w sumie tylko jak programujesz pod DEV C++
Jezeli jej nie zastosujesz to ci sie po prostu program nie wlaczy  |
dzięki za wyjaśnienie, na szczęście ja się z dala od takich progsów trzymam
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Kepszt
Kierowca Wywrotki
Dołączył: 20 Lis 2006
Posty: 58
Przeczytał: 0 tematów
Ostrzeżeń: 0/5
|
Wysłany: Pią 15:33, 25 Maj 2007 Temat postu: |
|
|
Pepe napisał: | ta komenda jest potrzebna w sumie tylko jak programujesz pod DEV C++
Jezeli jej nie zastosujesz to ci sie po prostu program nie wlaczy  |
Program sie wlaczy ale po ostatniej komendzie nie zdazysz zobaczyc wyniku bo sam sie zamknie, polecenia sluza do blokowania konsoli.
Post został pochwalony 0 razy
|
|
Powrót do góry |
|
 |
|
|
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
|
fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001, 2005 phpBB Group
|