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

Steve Holden steve at holdenweb.com
Tue Jan 25 00:44:01 CET 2005


Tim Roberts wrote:

> 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
> 
one word: decimal

> 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>
> 
:-)

regards-ly y'rs
-- 
Steve Holden               http://www.holdenweb.com/
Python Web Programming  http://pydish.holdenweb.com/
Holden Web LLC      +1 703 861 4237  +1 800 494 3119



More information about the Python-win32 mailing list