Leibniz_Pi.py
Bengt Richter
bokr at oz.net
Sat Oct 12 03:14:45 EDT 2002
More information about the Python-list mailing list
Sat Oct 12 03:14:45 EDT 2002
- Previous message (by thread): Leibniz_Pi.py
- Next message (by thread): Leibniz_Pi.py
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Fri, 11 Oct 2002 10:14:38 -0700, "Cousin Stanley" <CousinStanley at HotMail.com> wrote: >Yesterday in the news group comp.lang.java.help >I found a Java example of the Leibniz Pi approximation >and converted the Java code to Python ...=20 > >The numerical results from either version=20 >using a LARGE number of terms as a program argument >provide approximations for the number Pi that seems correct ...=20 > >Using 1 million terms as an input argument, >the Java version is a bit faster, which I think >is expected ...=20 > > On a 250 MHz Win98 machine ...=20 > =20 > Java SDK 1.4 ....... ~ 3-4 seconds > Python 2.2.1 ......... ~ 9-10 seconds > >Since I am fairly new to BOTH Java AND Python, >I'm wondering if there are any ...=20 > > obvious oversights ??? > Python improvements ??? > >Python code follows ... > >Cousin Stanley > >---------------------------------------------------------------- > >'''=20 > Leibniz_Pi.py > > Pi =3D 4 * ( 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 ... ) > > Using one million terms provides a good approximation ... > > Posted to the NewsGroup > comp.lang.java.help 2002-10-10=20 > By Jonas Lindstr=F6m > > Converted to Python > By Stanley C. Kitching >''' > >import sys >print '\n Approximate Pi via Leibniz Sequence ' > >def calculate_pi( nTerms ) : > > limit =3D ( 2 * nTerms ) - 1=20 > > if ( ( limit - 1 ) % 4 ) =3D=3D 0 : =20 > sign =3D +1.0=20 > else :=20 > sign =3D -1.0 > > sum =3D 0.0 > > for i in range( limit , 0 , -2 ) :=20 > sum +=3D sign / i > sign =3D -sign > > return 4.0 * sum=20 > >nTerms =3D int( sys.argv[ 1 ] )=20 > >Pi =3D calculate_pi( nTerms ) > >print '\n Terms : ' , nTerms >print '\n Pi : ' , Pi > > [ 0:01] C:\pywk\pi>pisigint.py (Type Ctrl-C to stop generating pi) 50 4085.12 dig/sec 31415926535897932384626433832795028841971693993751 100 3292.99 dig/sec 05820974944592307816406286208998628034825342117067 150 2422.61 dig/sec 98214808651328230664709384460955058223172535940812 200 1851.27 dig/sec 84811174502841027019385211055596446229489549303819 250 1473.79 dig/sec 64428810975665933446128475648233786783165271201909 300 1277.74 dig/sec 14564856692346034861045432664821339360726024914127 350 1087.28 dig/sec 37245870066063155881748815209209628292540917153643 400 1003.15 dig/sec 67892590360011330530548820466521384146951941511609 450 852.50 dig/sec 43305727036575959195309218611738193261179310511854 500 742.55 dig/sec 80744623799627495673518857527248912279381830119491 550 666.12 dig/sec 29833673362440656643086021394946395224737190702179 600 624.75 dig/sec 86094370277053921717629317675238467481846766940513 650 595.61 dig/sec 20005681271452635608277857713427577896091736371787 700 535.77 dig/sec 21468440901224953430146549585371050792279689258923 750 501.08 dig/sec 54201995611212902196086403441815981362977477130996 800 470.28 dig/sec 05187072113499999983729780499510597317328160963185 850 436.58 dig/sec 95024459455346908302642522308253344685035261931188 900 333.36 dig/sec 17101000313783875288658753320838142061717766914730 950 363.52 dig/sec 35982534904287554687311595628638823537875937519577 818577805321712 965 Total digits (965 total digits) (I hit Ctrl-C fairly shortly). You can redirect the pi digits, and watch the left part on a single line being rewritten, which looks like so: [ 0:10] C:\pywk\pi>python pisigint.py >zz.txt (Type Ctrl-C to stop generating pi) 2455 Total digits [ 0:10] C:\pywk\pi> ----< pisigint.py >------------------------- #!/usr/bin/python # Print digits of pi forever, unless you hit Ctrl-C # The output is split between stderr and stdout so that you can # redirect the pi digits to a file, like so # python pisiginit.py > pidigits.txt # and still see how many and how fast digits are being output. The latter # info is rewritten without \n, so it does not scroll. If you don't # redirect you see the latter to the left and the pi digits 50 at a time # to the right. This is a modified version of the algorithm as found # somewhere on the Ruby site. # # The algorithm, using Python's 'long' integers ("bignums"), works # with continued fractions, and was conceived by Lambert Meertens. # # See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton, # published by Prentice-Hall (UK) Ltd., 1990. import sys, signal from time import clock class SigHandler: def __init__(self): self.signaled = 0 def __call__(self, sn, sf): self.signaled += 1 sh = SigHandler() oldHandler = signal.signal(signal.SIGINT,sh) k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L digits=0 # count to show progress lines = 0 digline = [] start=clock() sys.__stderr__.write('\r(Type Ctrl-C to stop generating pi)\n') while not sh.signaled: # Next approximation p, q, k = k*k, 2*k+1, k+1 a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1 # Print common digits d = a / b d1 = a1 / b1 while d == d1: digits += 1 #sys.__stderr__.write('\r%5d' % (digits,)) digline.append(d) if len(digline)==50: sys.__stderr__.write('\r%5d %8.2f dig/sec ' % (digits, 50.0/(clock()-start))) lines += 1 print ''.join(map(lambda x: chr(x+48),digline)) digline = [] start=clock() a, a1 = 10*(a%b), 10*(a1%b1) d, d1 = a/b, a1/b1 sys.__stderr__.write('\r'+' '*24) if digline: print ''.join(map(lambda x: chr(x+48),digline)) sys.__stderr__.write('\r%5d Total digits \n'% (lines*50+len(digline))) print '\n(%d total digits)' % (lines*50+len(digline)) signal.signal(signal.SIGINT,oldHandler) -------------------------------------------- Regards, Bengt Richter
- Previous message (by thread): Leibniz_Pi.py
- Next message (by thread): Leibniz_Pi.py
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list