#!/usr/bin/python import math def preciseAcot(value, scale): """This function calculates the arc cotan of a value scaled by the scale factor. It uses long integer arithmetic to get more precision.""" n = 1 term = preciseAcotTerm(value, 1, scale) sumTerms = 0 while (abs(term) >= 1): sumTerms += term n += 1 term = preciseAcotTerm(value, n, scale) return sumTerms def preciseAcotTerm(value, n, scale): if ( n % 2 ) == 0: sign = -1 else: sign = 1 numerator = (sign * scale) denominator = ((value ** ((2 * n) - 1)) * ((2 * n) - 1)) retVal = numerator // denominator return retVal def evenFibonacci(): """ An unbounded generator for the even terms (F2, F4, F6, etc.) of the Fibonacci sequence. Based upon recipe 19.3, by Tom Good and Leandro Mariano Lopez, from the Python Cookbook. The sequence starts from F2.""" F_odd, F_even = 1, 2 while True: yield F_even F_odd = F_odd + F_even F_even = F_odd + F_even def sumExpansion(scale): # This function sums up the arc cotan function values of the even terms # in the Fibonacci sequence to produce an approximation of pi/4 evenFiboGen = evenFibonacci() Fn = evenFiboGen.next() term = preciseAcot(Fn, scale) sumTerms = 0L while (abs(term) >= 1): sumTerms += term Fn = evenFiboGen.next() term = preciseAcot(Fn, scale) return sumTerms def calculatePi(precision): # Add a couple of extra decimal places to the precision to take rounding # error of terms in the expansion into account. Scale back down for the # output. extraDigits = ( long(math.ceil(math.log10(precision * 30))) + 1) scale = pow(10, (precision + extraDigits)) piDigits = 4 * sumExpansion(scale) return piDigits // pow(10, extraDigits) if __name__ == "__main__": import sys precision = int(sys.argv[1]) print "Hello world. Here are", precision,"digits of pi:\n", calculatePi(precision)