[python-win32] on the way to find pi!

Tim Roberts timr at probo.com
Mon Jan 24 22:51:16 CET 2005


On Sun, 23 Jan 2005 10:28:47 -0800 (PST), Ali Polatel 
<alipolatel at yahoo.com> wrote:

>I found a code which calculates pi with an interesting algorithm the programme code is below:
>from sys import stdout
>def f((q,r,t,k)):
>    n = (3*q+r) / t
>    if (4*q+r) / t == n:
>        return (10*q,10*(r-n*t),t,k,n)
>    else:
>        return (q*k, q*(4*k+2)+r*(2*k+1),t*(2*k+1),k+1)
># Call pi(20) for first 20 digits, or pi() for all digits
>def pi(n=-1):
>    printed_decimal = False
>    r = f((1,0,1,1))
>    while n != 0:
>        if len(r) == 5:
>            stdout.write(str(r[4]))
>            if not printed_decimal:
>                stdout.write('.')
>                printed_decimal = True
>            n -= 1
>        r = f(r[:4])
>    #stdout.write('\n')
>if __name__ == '__main__':
>    from sys import argv
>    try:
>        digit_count = long(argv[1])
>    except:
>        digit_count=int(raw_input('How many digits? :'))
>        pi(digit_count)
>        
>This code gives the number in an unusual format like "3.1415'None'" it has a number part and a string part .
>

Your problem is that the function "pi" doesn't actually return 
anything.  If you do this, for example:
    print pi(5)
you will see 3.1415None.  The first 5 digits of pi come from the 
sys.stdout.write calls in the function, and the "None" comes from the 
print statement when it tries to display the result of the function.

I can certainly tell you how to change this code so that it returns a 
value instead of always printing to stdout, but first let me ask what 
you plan to do with it.  You said:

>Any idea how to seperate this 'None' from the number and make it a real normal number on which I can do operations like +1 -1 or like that 
>

This algorithm is useless as a way to generate a "real normal number", 
because there are no "real normal numbers" that keep an infinite number 
of floating point digits.  This function is fun for generating 120 
decimal digits for amusement purposes, but it has no practical value.  
If all you want is a "pi" that you can use in computation, you cannot do 
better than this:

    from math import pi

Double-precision floating point arithmetic on x86 machines has about 15 
digits of precision.  Even if you generate pi(80) using your function, 
as soon as you convert it to a float to use it in a function, it will 
lose all but the first 15 digits.

Here is your code, changed so that pi() returns a string value:

import sys

def f((q,r,t,k)):
    n = (3*q+r) / t
    if (4*q+r) / t == n:
        return (10*q,10*(r-n*t),t,k,n)
    else:
        return (q*k, q*(4*k+2)+r*(2*k+1),t*(2*k+1),k+1)

# Call pi(20) for first 20 digits, or pi() for all digits
def pi(n=-1):
    s = []
    r = f((1,0,1,1))
    while n != 0:
        if len(r) == 5:
            s.append( str(r[4]) )
            n -= 1
        r = f(r[:4])
    s.insert( 1, '.' )
    return ''.join( s )

if __name__ == '__main__':
    try:
        digit_count = long(sys.argv[1])
    except:
        digit_count = int(raw_input('How many digits? :'))
    print pi(digit_count)
    print repr(float(pi(digit_count)))

and here is what happens when you try to use it in arithmetic:

C:\Tmp>x.py 5
3.1415
3.1415000000000002

C:\Tmp>x.py 10
3.141592653
3.141592653

C:\Tmp>x.py 15
3.14159265358979
3.14159265358979

C:\Tmp>x.py 20
3.1415926535897932384
3.1415926535897931

C:\Tmp>

-- 
- Tim Roberts, timr at probo.com
  Providenza & Boekelheide, Inc.



More information about the Python-win32 mailing list