Dzisiaj będzie o długich liczbach. Wiedzieliście, że Python w stałej Pi zawiera tylko 48 cyfr po przecinku? (a przynajmniej wersja 2.6) 3.141592653589793 (odtąd błędnie) 115997963468544185161590576171875. To stanowczo za mało! Tyle to ja liczyłem na liczydle w przedszkolu A ja chciałbym wiedzieć jaka jest liczba pięciotysięczna po przecinku ;-) Zademonstruję 3 metody liczenia liczby Pi.
Od razu mówię, nie pytajcie mnie o nic w związku z tymi metodami, bo zazwyczaj rozumiem tylko wstęp i pierwszy wzór z opisu.
I. Metoda Wallisa
Posłużymy się takim fajnym tworem jak generator (yield w pętli zamiast return)
def wallisFormulaGenerator(counterMax): counter = 0 while(counter <= counterMax): counter += 1 yield (4*(counter**2))/(4*(counter**2)-1) def gimmePiBaby(loops): result = 1 for value in wallisFormulaGenerator(loops): result *= value return 2*result print(gimmePiBaby(10000))
Ta metoda jest najsłabsza, po 18 obrotach mamy dopiero 3.1, po 492 3.14, a dopiero po 8476 3.1415.
II. Metoda Leibnitza
W moim przypadku mocno oszukana ta metoda, ale działa poprawnie. I dużo szybciej!
minus = True partial = 1 denominator = 3 for i in range(100000): if minus: partial -= 1/denominator minus = False else: partial += 1/denominator minus = True denominator += 2 result = 4 * partial
Jest lepiej, obliczenia wykonywały się 3x szybciej niż poprzednio.
III. Metoda Abrahama Sharpa
Najwydajniejsza z wyżej przedstawionych. Na pewno są wydajniejsze, ale dla określenia liczby nr 5000 wystarczy. Aby wypisać tyle liczb ile nas interesuje, zwykły obiekt typu float nie wystarczy, potrzebujemy biblioteki BigFloat. Niestety nie daje się zainstalować z wersją 3 Pythona mimo użycia 2to3, więc pozostaje wbudowane w Ubuntu 2.6.
import bigfloat with bigfloat.precision(17000): minus = True partial = bigfloat.BigFloat(1) denominator = 3 for i in range(1, 500000): if minus: partial -= (1/((bigfloat.pow(3,i))*denominator)) minus = False else: partial += (1/((bigfloat.pow(3,i))*denominator)) minus = True denominator += 2 result = 6 * ((1/bigfloat.sqrt(3)) * partial)
Mój procek za 45zł 500 000 obrotów wykonał w 2339 sek., a dzisiejszy wpis sponsoruje cyferka 1 będąca wartością pięciotysięczną po przecinku.
Mam nadzieję, że chociaż gimnazjalistom algorytmy się przydadzą…
Podobne wpisy:

O autorze