Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Rounding to Zero in Python

I have a program meant to approximate pi using the Chudnovsky Algorithm, but a term in my equation that is very small keeps being rounded to zero.

Here is the algorithm:

import math
from decimal import *
getcontext().prec = 100

pi = Decimal(0.0)
C = Decimal(12/(math.sqrt(640320**3)))
k = 0
x = Decimal(0.0)
result = Decimal(0.0)
sign = 1
while k<10:
    r = Decimal(math.factorial(6*k)/((math.factorial(k)**3)*math.factorial(3*k)))
    s = Decimal((13591409+545140134*k)/((640320**3)**k))
    x += Decimal(sign*r*s)
    sign = sign*(-1)
    k += 1
result = Decimal(C*x)
pi = Decimal(1/result)


print Decimal(pi)

The equations may be clearer without the "decimal" terms.

import math

pi = 0.0
C = 12/(math.sqrt(640320**3))
k = 0
x = 0.0
result = 0.0
sign = 1
while k<10:
    r = math.factorial(6*k)/((math.factorial(k)**3)*math.factorial(3*k))
    s = (13591409+545140134*k)/((640320**3)**k)
    x += sign*r*s
    sign = sign*(-1)
    k += 1
result = C*x
pi = 1/result

print pi

The issue is with the "s" variable. For k>0, it always comes to zero. e.g. at k=1, s should equal about 2.1e-9, but instead it is just zero. Because of this all of my terms after the first =0. How do I get python to calculate the exact value of s instead of rounding it down to 0?

like image 669
jb37 Avatar asked Apr 11 '13 00:04

jb37


2 Answers

Try:

s = Decimal((13591409+545140134*k)) / Decimal(((640320**3)**k))

The arithmetic you're doing is native python - by allowing the Decimal object to perform your division, you should eliminate your error.

You can do the same, then, when computing r.

like image 183
Sajjan Singh Avatar answered Sep 21 '22 08:09

Sajjan Singh


A couple of comments.

If you are using Python 2.x, the / returns an integer result. If you want a Decimal result, you convert at least one side to Decimal first.

math.sqrt() only return ~16 digits of precision. Since your value for C will only be accurate to ~16 digits, your final result will only be accurate to 16 digits.

like image 37
casevh Avatar answered Sep 21 '22 08:09

casevh