Compute pi to base 12 using Python?

Bengt Richter bokr at oz.net
Thu Apr 14 00:56:32 EDT 2005


On Wed, 13 Apr 2005 21:52:45 GMT, bokr at oz.net (Bengt Richter) wrote:
[...]
>
>If you replace
>            a, a1 = 10L*(a%b), 10L*(a1%b1)
>with
>            a, a1 = 12L*(a%b), 12L*(a1%b1)
>
>and
>    sys.stdout.write(`int(d)`)
>with
>    sys.stdout.write('%X'%d`)
Typo, sorry ----------------^
that back-tick should not be there ;-/
>
>and run it, I think it will do what you want, even though I haven't worked through exactly
>what it's doing, though it's pretty. (For confidence I just tried it and decoded the result
>far enough to match math.pi exactly ;-)
>
>(the %X formats hex, but for single digits that's fine for base 12, giving A for 10 and B for 11.
>If you want bases >16 you'll have to use something like '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[digitvalue])
>
>
BTW, I would make this into a base-parameterized generator, something like

 >>> def pigen(base=10, ndigits=True):
 ...     base = long(base)
 ...     k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
 ...     while ndigits:
 ...         # Next approximation
 ...         p, q, k = k*k, 2L*k+1L, k+1L
 ...         a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
 ...         # Print common digits
 ...         d, d1 = a/b, a1/b1
 ...         while d == d1:
 ...             yield int(d)
 ...             if ndigits is not True:
 ...                 ndigits -= 1
 ...                 if ndigits == 0: break
 ...             a, a1 = base*(a%b), base*(a1%b1)
 ...             d, d1 = a/b, a1/b1
 ...
 >>> def pidigits(base, ndigits=True, digchars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
 ...     assert base>=2 and base <= len(digchars) and ndigits>=0
 ...     for d in pigen(base, ndigits):
 ...         yield digchars[d]

[ I just realized the original had tabs, so the above is fixed and pasted after the below ]
 ...
 >>> import sys
 >>> for d in pidigits(10, 60): sys.stdout.write(d)
 ...
 314159265358979323846264338327950288419716939937510582097494>>>
 >>>
 >>> print ''.join(d for d in pidigits(10,60)
 ...
 ... )
 314159265358979323846264338327950288419716939937510582097494
 >>> print ''.join(d for d in pidigits(10,60))
 314159265358979323846264338327950288419716939937510582097494
 >>> print ''.join(d for d in pidigits(12,60))
 3184809493B918664573A6211BB151551A05729290A7809A492742140A60
 >>> print ''.join(d for d in pidigits(26,60))
 33HIGBEBOHJHE3DB7DGJ6AK3G6JK8HND4G12A1IP8LGGL63C4BCK4NHE8G8O
 >>> print ''.join(d for d in pidigits(36,60))
 353I5AB8P5FSA5JHK72I8ASC47WWZLACLJJ9ZN98LTXM61VYMS1FRYTCI4U2
 >>> print ''.join(d for d in pidigits( 2,60))
 300100100001111110110101010001000100001011010001100001000110
 >>>
 >>> for d in pidigits(10): sys.stdout.write(d); sys.stdout.flush()
 ...
 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211
 706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895
 493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360
 726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138
 414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272
 489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317
 675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014
 654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999
 837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783
 875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053
 217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530
 185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838
 175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783
 74494482553797747268471040475346462080466842590694912933136770289891521047521Traceback (most rec
 ent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 3, in pidigits
   File "<stdin>", line 16, in pigen
 KeyboardInterrupt

To make a file for your friend,

 >>> open('pi12.txt','w').write(''.join(c for c in pidigits(12, 3003)))

That didn't take very long. No line breaks though. You can do that quick and dirty with

 >>> open('pi12by60.txt','w').write(
 ...         ''.join(c+'\n'[:(i+1)%60==0] for i,c in enumerate(pidigits(12, 3003)))+'\n')
 >>>

(adding the last EOL since we know 3003%60 =!0 ;-)
 
You could speed up the initial burst a lot, but after a while the data passing overhead is not
a significant part of the whole time.

Hm, ... that first digit still needs to be fixed for base <4 ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list