[C++] Obliczanie liczby PI

0

Witam,
Chciałbym obliczyć liczbe PI.
Korzystając z pewnej formuły na wikipedii zrobiłem to w ten sposób:

long double pi = 0;
for (int i=0; i<1500; i++)
  pi += (1/pow(16,i))*(4/(8*i+1) - 2/(8*i+4) - 1/(8*i+5) - 1/(8*i+6));

Niestety wychodzi tylko 3,14159 i dalej nie liczy ;P.
Zapewne chodzi o coś związane z dokładnością zmiennej? Jak w takim razie inaczej to policzyć?

0

Pewnie wyświetlałeś to przez strumien cout. Domyslnie ma on ustawone wyswietlanie chyba 6 albo 5 znaków po przecinku. Żeby to zmienić musisz uzyć setprecision().
Natomiast co do dokładności to long double ma ja największą z pośród typów podstawowych.

0

Mimo to nadal wynik:
3.1415926535897931
nie jest satysfakcjonujący
Tymbardziej, że ostatnia cyfra powinna być 2-ka ;).

Skoro liczą przybliżenie do wielu miliardów to musi być jakaś inna metoda niż ten mój sposób, który jest ograniczany przez typ zmiennej.

0

Tak, własna arytmetyka

0

Ja bym użył wzoru Leibniz'a, bo ten którego używasz ma 16^k gdzie k->oo. Ponadto stworzył bym nowy typ danych który liczby zapisywał by w postaci mianownika i licznika (wszystko w int64). Więc dopiero na samym końcu bym podzielił dwie duże liczby całkowite.

0
Mammoth napisał(a)

Ponadto stworzył bym nowy typ danych który liczby zapisywał by w postaci mianownika i licznika (wszystko w int64).

O, więc PI jest wymierne?

0
manfredek napisał(a)
Mammoth napisał(a)

Ponadto stworzył bym nowy typ danych który liczby zapisywał by w postaci mianownika i licznika (wszystko w int64).

O, więc PI jest wymierne?

Panu już dziękujemy [glowa]
Chodzi o obliczenie przybliżenia liczby pi a ułamki mają usunąć niedokładności liczb zmiennoprzecinkowych...

0
sciana napisał(a)

Chodzi o obliczenie przybliżenia liczby pi a ułamki mają usunąć niedokładności liczb zmiennoprzecinkowych...
Niby - ale jak ktoś chce dokładnie, to...

sciana napisał(a)

Panu już dziękujemy [glowa]
Niektórzy są głupi i ni kijem ich nie ruszysz. Ot, czto.

0

Wzór Leibniz'a jest jednym z gorszych sposobów, strasznie wolno się zbiega
Można co prawda użyć jakichś technik przyśpieszania zbieżności ale to osobny temat.
Wart zobaczyć http://mathworld.wolfram.com/PiFormulas.html
A tam polecam sposób Machin'sa, np. (5) w podanym linku
Potrzebne jest dzielenie "długiej" liczby przez prosty int oraz dodawanie i odejmowanie "długich" liczb.
Liczba "długa" to np. tablica cyfr
arctg liczone tak jak w Laibniz'u, ale liczy się dla ułamka a nie dla jedności, dramatycznie szybciej zbieżne
Jest to stosunkowo łatwe i działa nawet sensownie (cały programik ma szansę zmieścić się na jednym ekranie, no może na dwu), i można zobaczyć parę tysięcy cyfr Ludolfiny

0

Nie w C++, ale jak ktoś będzie chciał, to przetłumaczy, algorytm jest prosty:

public static string GetPi(int decimalPlaces)
{
    const int offset = 154;

    int additionalBytes = (decimalPlaces / 100) * 5;

    byte[] buffer = new byte[offset + decimalPlaces + additionalBytes];
    new WebClient().OpenRead("http://3.141592653589793238" + 
        "462643383279502884197169399375105820974944592.com/index314.html")
        .Read(buffer, 0, offset + decimalPlaces + additionalBytes);

    return "3." + Encoding.Default.GetString(buffer, offset, decimalPlaces + additionalBytes)
                    .Replace("  \n  ", "");
}
0

Zepsułeś całą zabawę :(

0

Heh, dobry algorytm :P Ale może nie zamykajmy tematu, bo sam się tym zainteresowałem jak to zaimplementować, żeby liczyło te cyfry po przecinku.

0

Sposobem jakim 300 lat temu John Machin obliczył 100 cyfr po przecinku,
10'000 cyfr policzyłem w 2.5 sekundy (2^6 wierszy).
Ciekawe ile czasu John poświęcił tej pracy?

user image

Jedyny, troszkę trudniejszy fragment to dzielenie "długiej" liczby.
Początek mojego programiku.

#include <stdio.h>
#include <time.h>

#define RADIX 10000 // podstawa pozycyjnego systemu liczbowego
#define MAX 2502    // uzyskamy (MAX-1)*4 cyfr
typedef unsigned int uint;

uint podziel(uint t[], uint a[], uint d){  // t= a/d
	uint k=1,i,s,p=0;
	for(i=0;i<MAX; i++){
		s= a[i] + p*RADIX;
		p= s % d;
		t[i]= s / d;
		if(t[i])k=0;
	}
	return k; //  k==1 gdy t==0
}
0

nie mieliśmy tego na matmie jeszcze i zadam takie pytanie (być może banalne): co to za funkcja arctan? Ciężko mi cokolwiek o niej znaleźć.

0

http://pl.wikipedia.org/wiki/Arctan - ja też nie miałem, ale wiki i google nie gryzie

0
Rev.pl napisał(a)

new WebClient().OpenRead("http://3.141592653589793238" +
"462643383279502884197169399375105820974944592.com/index314.html")

somekind napisał(a)

Zepsułeś całą zabawę

radoslav006 napisał(a)

Heh, dobry algorytm Ale może nie zamykajmy tematu, bo sam się tym zainteresowałem jak to zaimplementować, żeby liczyło te cyfry po przecinku.

Nie no sorry, wy tak na poważnie bo już nie wiem co o tym myśleć...?

0
johny_bravo napisał(a)

http://pl.wikipedia.org/wiki/Arctan

No tak, za szybko się zapytałem jak zawsze ;-P

0

Przypomne, jutro 3.14 :-)

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