2015-02-02 14 views
9

Sono un principiante pitone e voglio calcolare il pi. Ho provato a utilizzare l'algoritmo Chudnovsky perché ho sentito che è più veloce di altri algoritmi.Calcolo pi Python?

Questo è il mio codice:

from math import factorial 
from decimal import Decimal, getcontext 

getcontext().prec=100 

def calc(n): 
    t= Decimal(0) 
    pi = Decimal(0) 
    deno= Decimal(0) 
    k = 0 
    for k in range(n): 
     t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k) 
     deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k)) 
     pi += Decimal(t)/Decimal(deno)         
    pi = pi * Decimal(12)/Decimal(640320**(1.5)) 
    pi = 1/pi 
    return pi 

print calc(25) 

Per qualche motivo questo codice produce il vakue di pi greco fino a soltanto 15 decimali rispetto al valore accettabile. Ho cercato di risolverlo aumentando il valore di precisione; questo aumenta il numero di cifre, ma solo i primi 15 sono ancora precisi. Ho provato a cambiare il modo in cui calcola l'algoritmo e non ha funzionato neanche. Quindi la mia domanda è, c'è qualcosa che può essere fatto a questo codice per renderlo molto più accurato o dovrei usare un altro algoritmo? Apprezzerei molto l'aiuto perché non so come operare con così tante cifre in python. Vorrei essere in grado di controllare il numero di (corrette) cifre determinate e visualizzate dal programma - sia 10, 100, 1000, ecc

+0

Proprio per il confronto, ecco qualche codice Chudnovsky di lavoro: http://www.craig-wood.com/nick/articles/pi-chudnovsky/ – runDOSrun

risposta

13

Sembra che si stanno perdendo di precisione in questa linea:

pi = pi * Decimal(12)/Decimal(640320**(1.5)) 

Provare a utilizzare:

pi = pi * Decimal(12)/Decimal(640320**Decimal(1.5)) 

Questo accade perché, anche se Python in grado di gestire interi scala arbitraria, non fare così bene con i galleggianti.

Bonus

Un'implementazione singola linea utilizzando un altro algoritmo (la BBP formula):

from decimal import Decimal, getcontext 
getcontext().prec=100 
print sum(1/Decimal(16)**k * 
      (Decimal(4)/(8*k+1) - 
      Decimal(2)/(8*k+4) - 
      Decimal(1)/(8*k+5) - 
      Decimal(1)/(8*k+6)) for k in range(100)) 
+0

Grazie tanto! Ha funzionato. È incredibile per me come un cambiamento così piccolo abbia fatto la differenza. –

+0

@Juan Lopes Ciao puoi aiutarmi a scrivere lo pseudocodice per questa formula BBP per calcolare PI –

-7

Se si desidera trovare il valore di pi solo fino a 53 cifre e se sei un principiante, quindi è possibile utilizzare questo:

print 'Pi value till 53 digits:%1.53f'%(22.0/7) 
+7

22/7 non è π. È un'approssimazione che va bene a 2 cifre dopo il punto, quindi non è certamente abbastanza buono se vuoi 53 cifre dopo il punto. (Ciò che mostri non fornisce 53 cifre accurate per 22/7, sia.) –

+1

Prova a rimuovere questa risposta, per favore. –

3

per le persone che vengono qui solo per ottenere un pronto così luzione per ottenere precisione arbitraria di pi greco con Python:

import decimal 

def pi(): 
    """ 
    Compute Pi to the current precision. 

    Examples 
    -------- 
    >>> print(pi()) 
    3.141592653589793238462643383 

    Notes 
    ----- 
    Taken from https://docs.python.org/3/library/decimal.html#recipes 
    """ 
    decimal.getcontext().prec += 2 # extra digits for intermediate steps 
    three = decimal.Decimal(3)  # substitute "three=3.0" for regular floats 
    lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24 
    while s != lasts: 
     lasts = s 
     n, na = n + na, na + 8 
     d, da = d + da, da + 32 
     t = (t * n)/d 
     s += t 
    decimal.getcontext().prec -= 2 
    return +s    # unary plus applies the new precision 

decimal.getcontext().prec = 1000 
pi = pi()