[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