Strona 1 z 1

Zmienne w c++

: 11 sie 2007, o 02:10
autor: Sokół
Okej, od dwoch dni ucze sie programowania w c++. Przerabiam kurs ktory sie ukazal w ktorym expercie, dzisiaj przyszedl czas na zmienne, ale wybieglem sobie troche do przodu, bo potrzebna mi byla petla. Chcialem sobie zrobic implementacje metody leibniza do obliczania liczby pi.
\(\displaystyle{ \sum_{n=0}^{\infty} \frac{(-1)^{n}}{2n+1} = \frac{1}{1} - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \frac{1}{9} - s = \frac{\pi}{4}}\)

jednak jak moj program wypisuje pi, to tylko 4 lub 5 miejsc po przecinku. Chcialbym, zeby tak z dwadziescia miejsc po przecinku Jak to zrobic? Kod programu;
(pisalem w devie, gdzie sie kompiluje)

Kod: Zaznacz cały

#include <iostream>
using namespace std;
int main()
{
    float pi =0;
    float mianownik;
    for(int licznik= 0; licznik< 10000; licznik++)
                 {
                    if(licznik%2==1)
                                   {
                                        mianownik=2*licznik+1;
                                        pi=pi-4/mianownik;
                                   }
                    else
                                   {
                                        mianownik=2*licznik+1;
                                        pi=pi+4/mianownik;
                                   }
              
                 }




                  cout << "pi wynosi: " << pi;
}

krotkie wyjasnienie kodu. To rozwiniecie ze wzoru pomnozylem sobie obustronnie razy cztery. A ze raz sie dodaje, a raz odejmuje, to powstal warunek ktory sprawdza modulo licznika. Mozna petle zmniejszyc, ale przyblizenie liczby pi bedzie mniej dokladne.

[ Dodano: 11 Sierpnia 2007, 02:13 ]
zmienna licznik nie oznacza licznika na gorze w ulamku! "Licznik" to jest hmmm zmienna ktora mowi ktory jest krok pętli.

Zmienne w c++

: 11 sie 2007, o 10:09
autor: luka52
Zamiast zmiennych typu float użyj double lub long double choć i tak te typy mają swoje ograniczenia (tak na szybko sprawdzałem i różnica to jest chyba 1 cyfra więcej ). Jeżeli zaś bardzo zależy Ci na uzyskaniu możliwie wysokiej precyzji - zainteresuj się biblioteką GMP ... ic_Library .

Zmienne w c++

: 11 sie 2007, o 18:33
autor: bagin
Możesz użyć na strumieniu funkcji setprecision(), która jako argument pobiera ilość miejsc po przecinku jaka ma zostać wyświetlona. Powinno wyglądać to tak:

cout

Zmienne w c++

: 11 sie 2007, o 19:01
autor: luka52
Jednak funkcja setprecision() wymaga dodatkowego pliku nagłówkowego iomanip o ile się nie mylę.

Zmienne w c++

: 11 sie 2007, o 22:07
autor: smiechowiec
można jeszcze dodać, że analogiczny efekt uzyskamy korzystając z formatowania zwykłej funkcji printf.
Dla 12 bajtowego typu long double dałoby się wycisnąć pecyzję ok 30.
Po tych uwagach Twój program dla dev-cpp

Kod: Zaznacz cały

#include <iostream> 
#include <iomanip>
using namespace std;

int main() { 
    double pi = 0.0; 
    double mianownik; 
    for(int licznik = 0; licznik < 10000; licznik++) { 
		if( (licznik %2) ==1) { 
			mianownik = (2 * licznik) + 1;
            pi = pi - (4 / mianownik);
		} 
		else { 
			mianownik = (2 * licznik) + 1;
            pi = pi + (4 / mianownik);
		}
	}
	printf("pi wynosi: %20.18f
", pi);
	cout << "pi wynosi: " << setprecision(20) << pi; 
} 

Zmienne w c++

: 23 sie 2007, o 01:08
autor: Sokół
luka52 pisze:Zamiast zmiennych typu float użyj double lub long double choć i tak te typy mają swoje ograniczenia (tak na szybko sprawdzałem i różnica to jest chyba 1 cyfra więcej :| ). Jeżeli zaś bardzo zależy Ci na uzyskaniu możliwie wysokiej precyzji - zainteresuj się biblioteką GMP :arrow: .
MS-DOS and MS Windows
On an MS-DOS system DJGPP can be used to build GMP, and on an MS
Windows system Cygwin, DJGPP and MINGW can be used. All three are
excellent ports of GCC and the various GNU tools.

`

Kod: Zaznacz cały

http://www.cygwin.com/
'
`http://www.delorie.com/djgpp/'
`http://www.mingw.org/'

Microsoft also publishes an Interix "Services for Unix" which can
be used to build GMP on Windows (with a normal `./configure'), but
it's not free software.

MS Windows DLLs
On systems `*-*-cygwin*', `*-*-mingw*' and `*-*-pw32*' by default
GMP builds only a static library, but a DLL can be built instead
using

./configure --disable-static --enable-shared

Static and DLL libraries can't both be built, since certain export
directives in `gmp.h' must be different.

A MINGW DLL build of GMP can be used with Microsoft C. Libtool
doesn't install a `.lib' format import library, but it can be
created with MS `lib' as follows, and copied to the install
directory. Similarly for `libmp' and `libgmpxx'.

cd .libs
lib /def:libgmp-3.dll.def /out:libgmp-3.lib

MINGW uses the C runtime library `msvcrt.dll' for I/O, so
applications wanting to use the GMP I/O routines must be compiled
with `cl /MD' to do the same. If one of the other C runtime
library choices provided by MS C is desired then the suggestion is
to use the GMP string functions and confine I/O to the application.
to chyba oznacza, ze na xpeku z devem 4.9.9.2 (MinGW) nie moge tego uzywac ;(

Zmienne w c++

: 24 sie 2007, o 00:03
autor: Xitami
Long double to 12 bajtów? Sprawdziłbym to, bo sądzę, że tylko 10 z czego da się "wycisnąć" około 19 cyfr, ale...
Przede wszystkim chodzi o to, że metoda Leibniz'a stosowana na wprost jest bardzo wolno zbieżna. Wykonujesz 10000 iteracji i właśnie spodziewać się możesz 4 czy 5 poprawnych cyfr. Po miliardzie uzyskasz 9 cyfr. Czyli ile razy musi "obrócić" się pętla by uzyskać 20 dokładnych cyfr? Masz tyle czasu? :-)
Ale jest na to sposób, nawet nie jeden.
Można zmienić wzór wg którego liczysz (np. Machin), albo zastosować jakąś metodę przyśpieszającą zbieżność obliczeń szeregów naprzemiennych.
Taki mój mały wynalazek (choć Euler mnie chyba uprzedził :-)
Wstępnie policz ileś tam kroków, powiedzmy \(\displaystyle{ M}\). Następnie zbierz kolejne przybliżenia w tablicy. Niech będzie ich \(\displaystyle{ N}\). Teraz poczynając od pierwszego elementu w tablicy umieść średnią bieżącego i następnego. Uzyskasz \(\displaystyle{ N-1}\) "średnich". Powtarzaj to aż w tablicy zostanie tylko jedna wartość. Będzie to całkiem fajne \(\displaystyle{ \pi}\), ale precyzja nie przekroczy możliwości użytego typu zmiennoprzecinkowego. Poeksperymentuj z M i N.
Pętlę można zapisać nieco "lżej"

Kod: Zaznacz cały

while(licznik<K){
           pi -= 1/licznik++;
           pi += 1/licznik++;
}
Potrzebne jest tylko dodawanie, odejmowanie i liczenie odwrotności, to niewiele. Można by zrezygnować z float, a liczbę pamiętać w tablicy. W kolejnych komórkach kolejne cyfry. Dodawanie i odejmowanie bajecznie proste, mały kłopot z odwrotnością ale do przejścia. Tak kiedyś policzyłem pierwsze tysiące cyfr liczby \(\displaystyle{ \pi}\).
GMP zmieni tylko tyle, że da Ci wielką precyzję, ale kłopot z powolnością metody pozostanie.
Wesołej zabawy.

Zmienne w c++

: 24 sie 2007, o 23:02
autor: Sokół
Xitami pisze:GMP zmieni tylko tyle, że da Ci wielką precyzję, ale kłopot z powolnością metody pozostanie.
To był trening, tak, żeby poćwiczyć to co umiem. Żeby uzyskać szybkość zaimplementowałem metodę Ramanujana trzeci obrót pętli i dokładność chyba 16 cyfr po przecinku.