szukanie zaawansowane
 [ Posty: 4 ] 
Autor Wiadomość
Mężczyzna Offline
PostNapisane: 25 wrz 2009, o 18:11 
Użytkownik

Posty: 30
Lokalizacja: Kraków
Dostałem zadanie specjalne od nauczyciela informatyki, oczywiście się wywiązałem, za co zostałem nagrodzony. Dla własnej satysfakcji miałem jeszcze dopisać jedną funkcję. Ma ona sprawdzić dla ilu punktów stosunek równać się będzie faktycznej wartości Pi (przybliżyłem do 3.14159). Oczywiście tą funkcje też napisałem, ale pojawił się problem. Nie chce się ona zakończyć! Nawet przy kilkuset tysiącach punktów stosunek nie chce się równać liczbie pi. Dziwne... mam zatem pytanie czysto matematyczne: czy to w ogóle możliwe w sensie praktycznym, aby tym sposobem uzyskać liczbę Pi w zaokrągleniu 3.14159? Załączam mój kod. Chodzi konkretnie o funkcję "xxx".

//OBLICZANIE LICZBY PI METODĄ MONTE CARLO

#include <iostream>
#include <cstdlib>

using namespace std;

void wylicz(long licznik_kwadr, long licznik_kol, double x, double y, int n);
int xxx(long licznik_kwadr, long licznik_kol, double x, double y);
//***************************************************************
int main()
{
srand(time(NULL));
long licznik_kwadr, licznik_kol;
int n, ile;
double x, y;

cout<<"Ile razy wykonac operacje?\t";
cin>>ile;

for(int i=0; i<ile; i++)
wylicz(licznik_kwadr, licznik_kol, x, y, n);

cout<<endl<<"Pi rowne jest 3.14159 dla : "
<<xxx(licznik_kwadr, licznik_kol, x, y)<<" punktow.";

cout<<"\n\n\n";
system("PAUSE");
return EXIT_SUCCESS;
}
//**************************************************************
void wylicz(long licznik_kwadr, long licznik_kol, double x, double y, int n)
{
licznik_kwadr = 0;
licznik_kol=0;
n=rand();
for( ; licznik_kwadr<n; licznik_kwadr++)
{
x=(double)rand()/(RAND_MAX);
y=(double)rand()/(RAND_MAX);

if((x*x)+(y*y)<=1)
licznik_kol++;
}
cout<<endl<<"Dla "<<n<< " punktow liczba pi wynosi "<<(double)(4*licznik_kol)/licznik_kwadr<<endl;
}
//***************************************************************
int xxx(long licznik_kwadr, long licznik_kol, double x, double y)
{
const double pi = 3.14159;
licznik_kwadr = 0;
licznik_kol=0;
do {
x=(double)rand()/(RAND_MAX);
y=(double)rand()/(RAND_MAX);
licznik_kwadr++;

if((x*x)+(y*y)<=1)
licznik_kol++;
}while ((double)(4*licznik_kol)/licznik_kwadr != pi);
return licznik_kwadr;
}
Góra
Mężczyzna Offline
PostNapisane: 25 wrz 2009, o 18:31 
Gość Specjalny
Avatar użytkownika

Posty: 4952
Lokalizacja: Lozanna
Jeśli nie działa dla kilkuset tysięcy to sprawdź dla kilku milionów, aż do skutku. To nie jest zbyt dokładna metoda. Sprawdź jaką dokładność osiąga dla tej ilości punktów którą stosujesz. Może też być kłopot z błędami zaokrągleń itp.
Góra
Mężczyzna Offline
PostNapisane: 27 wrz 2009, o 14:27 
Użytkownik

Posty: 4
Lokalizacja: Kraków
Kod:
1
}while ((double)(4*licznik_kol)/licznik_kwadr != pi);


Ta linijka psuje Ci wszystko. Pamiętaj, że operujesz na liczbach zmiennoprzecinkowych, i że chcesz przerwać w momencie, w którym wynik będzie się zgadzał na pierwszych 5-6 pozycjach po przecinku. Ja bym ten warunek zamienił na jakiś taki:

Kod:
1
2
3
4
#include <cmath>
...
}while(fabs( aktualny_wynik - pi) > 1e-6);


P.s Ten kod który wrzuciłeś może się nie kończyć także z powodu linjki:
Kod:
1
n=rand();

w funkcji wylicz:)
Góra
Mężczyzna Offline
PostNapisane: 29 wrz 2009, o 21:01 
Użytkownik

Posty: 30
Lokalizacja: Kraków
kalq, dzięki wielkie, zmieniłem na ten warunek z "fabs" i działa. Cholera, że ja na to nie wpadłem :D Jeszcze raz dzięki.
Góra
Utwórz nowy temat Odpowiedz w temacie  [ Posty: 4 ] 


 Zobacz podobne tematy
 Tytuł tematu   Autor   Odpowiedzi 
 liczby pierwsze  Anonymous  4
 Obliczanie wyznacznika macierzy (z def.)  Anonymous  1
 [MPI] Metoda Cannona  Anonymous  0
 ZAMIANA systemow liczbowych, liczby niecalkowite.  bisz  1
 Liczby binarne...wartosci po przecinku  moczul  5
 
Atom [Regulamin Forum] [Instrukcja LaTeX-a] [Poradnik] [F.A.Q.] [Reklama] [Kontakt]
Copyright (C) ParaRent.com