1:#!/usr/bin/python 2:import math 3: 4: 5:def preciseAcot(value, scale): 6: """This function calculates the arc cotan of a value scaled by the scale 7: factor. It uses long integer arithmetic to get more precision.""" 8: n = 1 9: term = preciseAcotTerm(value, 1, scale) 10: sumTerms = 0 11: while (abs(term) >= 1): 12: sumTerms += term 13: n += 1 14: term = preciseAcotTerm(value, n, scale) 15: return sumTerms 16: 17: 18:def preciseAcotTerm(value, n, scale): 19: if ( n % 2 ) == 0: 20: sign = -1 21: else: 22: sign = 1 23: numerator = (sign * scale) 24: denominator = ((value ** ((2 * n) - 1)) * ((2 * n) - 1)) 25: retVal = numerator // denominator 26: return retVal 27: 28: 29:def evenFibonacci(): 30: """ An unbounded generator for the even terms (F2, F4, F6, etc.) of the 31: Fibonacci sequence. Based upon recipe 19.3, by Tom Good and Leandro Mariano 32: Lopez, from the Python Cookbook. The sequence starts from F2.""" 33: F_odd, F_even = 1, 2 34: while True: 35: yield F_even 36: F_odd = F_odd + F_even 37: F_even = F_odd + F_even 38: 39: 40:def sumExpansion(scale): 41: # This function sums up the arc cotan function values of the even terms 42: # in the Fibonacci sequence to produce an approximation of pi/4 43: evenFiboGen = evenFibonacci() 44: Fn = evenFiboGen.next() 45: term = preciseAcot(Fn, scale) 46: sumTerms = 0L 47: while (abs(term) >= 1): 48: sumTerms += term 49: Fn = evenFiboGen.next() 50: term = preciseAcot(Fn, scale) 51: return sumTerms 52: 53: 54:def calculatePi(precision): 55: # Add a couple of extra decimal places to the precision to take rounding 56: # error of terms in the expansion into account. Scale back down for the 57: # output. 58: extraDigits = ( long(math.ceil(math.log10(precision * 30))) + 1) 59: scale = pow(10, (precision + extraDigits)) 60: piDigits = 4 * sumExpansion(scale) 61: return piDigits // pow(10, extraDigits) 62: 63: 64:if __name__ == "__main__": 65: import sys 66: precision = int(sys.argv[1]) 67: print "Hello world. Here are", precision,"digits of pi:\n", calculatePi(precision)