Witam mam na zadanie napisać program na wzór Eulera http://upload.wikimedia.org/wikipedia/pl/math/1/0/5/105b8dc00dfe435e95ce5d02d1df8bbb.png a nie wiem jak to w ogóle ugryźć dopiero się uczę i mnie to przerosło :(
Bardzo proszę kogoś o pomoc.
Witam mam na zadanie napisać program na wzór Eulera http://upload.wikimedia.org/wikipedia/pl/math/1/0/5/105b8dc00dfe435e95ce5d02d1df8bbb.png a nie wiem jak to w ogóle ugryźć dopiero się uczę i mnie to przerosło :(
Bardzo proszę kogoś o pomoc.
Skorzystaj z tego wzoru(przyjemniejsza postac). Bardzo prosto wyliczyc pi z tego.
Ja by raczej spytał czy na pewno masz stosować ten wzór Eulera? Jest jeszcze wzór Eulera , który łatwo zaimplementować.
Ten wzór, który podałeś wymaga zastosowania bardzo nieporęcznej rekurencji, w której trudno kontrolować precyzję obliczeń.
W tym wzorze co dalem(jego), ale zapisanym inaczej wystarczy napisac kod na podstawie 2-giej linijki. Tam jedynie trzeba zapamietac poprzednik do mnozenia, bo zawsze mnozymy * licznik+1/mianownik+2 i sumowac wyniki dla zadanej ilosci krokow. Na samym koncu dodac 1 i pomnozyc przez 2 i cala robota.
Chyba użyje tego i ciul. Bo wykładowca spisał właśnie tak sobie z WIKI i mi ten przydzielił a tą przerobioną przez Ciebie Krycho dostał mój kolega. Trudno się mówi lepiej mieć coś źle niż nic nie mieć :)
to zamiast kombinować z podmianą zadania, napisz to bez oceniania dokładności. Nie jest to trudne.
Usupełnij to:
double eulrerContinuedFractionPi(int n) {
double an1=4; // tą wartość trzeba przyjąć w zasadzie losowo, bo nie da jej się łatwo estymować
for (;n>0;--n) {
an1 = 4 + (2*n+1)*(2*n+3)/an1;
}
...
}
Witam!
Pozwolę sobie podczepić się pod temat, jako że jest on analogiczny do mojego problemu. Próbuję napisać prosty program do wyliczenia Pi wykorzystując wzór Eulera
Kod wygląda następująco:
{
int i,n;
double mianownik,suma=1, x=2.;
printf("Podaj n: ");
scanf("%d", &n);
for (i=1; i<=n; i++){
mianownik=pow(x,2.);
suma+=1/mianownik;
x++;
}
}
Wynik zwracany jest oczywiście błędny, stąd i moja prośba aby ktoś rzucił okiem na kod i podzielił się swoimi spostrzeżeniami. Z góry dzięki za pomoc!
Pozdrawiam
@Edit.Otrzymany przeze mnie wynik należałoby pomnożyć przez 6 a następnie wyciągnąć z tego pierwiastek?;>
Dokładnie. Otrzymujesz przecież (pi^2)/6. Pomnożysz i spierwiastkujesz to dostaniesz pi. Sprawdzałem.
Ale komplikujesz !
unsigned n;
double suma;
printf("Podaj n: ");
scanf("%u",&n);
for(suma=0;n;--n) suma+=6./n/n;
suma=sqrt(suma);
@_13th_Dragon, dlaczego używasz tak dużo dzieleń?
unsigned n;
double suma = 0.0;
unsigned r = 1;
unsigned skl = 0;
printf("Podaj n: ");
scanf("%u",&n);
for(int i=0;i<=n;++i)
{
suma+=6.0/(skl+=r);
r+=2;
}
suma = sqrt(suma);
bogdans napisał(a):
@_13th_Dragon, dlaczego używasz tak dużo dzieleń?
unsigned n;
double suma = 0.0;
unsigned r = 1;
unsigned skl = 0;
printf("Podaj n: ");
scanf("%u",&n);
for(int i=0;i<=n;++i)
{
suma+=6.0/(skl+=r);
r+=2;
}
suma = sqrt(suma);
Chociażby w celach nie zagmatwania kodu tak że nie widzisz że nie działa.
http://ideone.com/rh2fao
Nie napisałem 6./(nn) tylko dla tego że nn może wyjść poza zakres unsigned, u ciebie ski1 wyjdzie poza unsigned.
_13th_Dragon napisał(a):
bogdans napisał(a):
@_13th_Dragon, dlaczego używasz tak dużo dzieleń?
unsigned n;
double suma = 0.0;
unsigned r = 1;
unsigned skl = 0;
printf("Podaj n: ");
scanf("%u",&n);
for(int i=0;i<=n;++i)
{
suma+=6.0/(skl+=r);
r+=2;
}
suma = sqrt(suma);
Chociażby w celach nie zagmatwania kodu tak że nie widzisz że nie działa.
http://ideone.com/rh2faoNie napisałem 6./(nn) tylko dla tego że nn może wyjść poza zakres unsigned, u ciebie ski1 wyjdzie poza unsigned.
Zjadło Ci chyba pierwiastkowanie na ideone. :]
@_13th_Dragon
Kod zoptymalizowałem(chociaż da się na pewno zrobić to jeszcze krócej) zaraz po tym jak doprowadziłem go do poprawnego działania:
int n;
double pi,suma=1,x=2;
printf("Podaj n: ");
scanf("%d", &n);
for (;n>0; --n,x++)
suma+=1/(pow(x,2));
pi = sqrt(suma*6);
Jestem początkujący także proszę o wyrozumiałość i jeszcze raz dzięki za sugestie!
kiluminati napisał(a):
@_13th_Dragon
Kod zoptymalizowałem ...
Nie zoptymalizowałeś. Wręcz na odwrót.
1/pow(x,2)
już lepiej dwa dzielenia 1./x/x
lub np: 1/((double)x*x)
Czegoś tu nie rozumiem dla maksymalnej precyzji dla double 82191236 wyliczonej przez @bogdans mamy
Ale to przecież nie jest maksymalna precyzja, składniki 1/(n*n) są nadal dodatnie, tylko są tak małe, że nie zmieniają sumy. Trzeba sumować od końca.
n = 2000000000;
suma = 0.0d;
for(i=n;i>=1;i--)
{
suma+=6.0/(i*i);
}
System.out.printf("pi = %25.23f\n",Math.sqrt(suma)); //pi = 3,14159265311232840000000
System.out.printf("pi = %25.23f\n",Math.PI); //pi = 3,14159265358979300000000
n = 82191237;
suma = 0.0d;
r = 1;
skl = 0;
for(i=0;i<=n;i++)
{
skl+=r;
suma+=6.0/skl;
r+=2;
}
System.out.printf("pi = %25.23f\n",Math.sqrt(suma)); //pi = 3,14159264365071700000000