Pi is the true magic number that countless people follow. I'm not quite sure about the charm of an irrational number that never repeats. In my opinion, I am happy to compute PI, which is the value of pi. Because pi is an irrational number, it is infinite. This means that any calculation of π is just an approximation. If you count 100 digits, I can calculate 101 bits and be more precise. So far, some people have chosen supercomputers to try to compute the most accurate π. Some extreme values include the calculation of 500 million bits of pi. You can even find 10 billion-bit text files that contain pi from the Web (note!). Downloading this file may take a while, and you won't be able to open it in a Notepad application that you normally use. )。 For me, how to compute pi in a few lines of simple python is my interest.
You can always use the Math.PI variable. It is included in the standard library and you should use it before you try to compute it yourself. In fact, we will use it to compute the accuracy. As a starting point, let's look at a very straightforward method of calculating pi. As usual, I'm going to use Python 2.7, and the same idea and code might be applied to different versions. Most of the algorithms we will use come from the Pi WikiPedia page and are implemented. Let's look at the following code:
Importsys
importmath
defmain (argv): Iflen (argv
)!=1: Sys.exit
(' Usage:calc_pi.py <n> ')
print ' \ncomputing Pi v.01\n '
a=1.0
b=1.0/math.sqrt (2)
t=1.0/4.0 p=1.0 foriinrange
(int ( SYS.ARGV[1]):
at= (a+b)/2
bt=math.sqrt (a*b)
tt=t-p* (a-at) **2
pt=2*p-a=at;b=bt;t=tt;p= PT
my_pi= (a+b) **2/(4*t)
accuracy=100* (MATH.PI-MY_PI)/my_pi
print "PI is approximately:" +str (MY_PI)
print "Accuracy with Math.PI:" +str (accuracy)
if__name__== "__main__":
Main (sys.argv[1:])
This is a very simple script that you can download, run, modify, and share freely with others. You can see output similar to the following:
You will find that although N is greater than 4, we do not have much improvement in approaching Pi precision. We can guess that even if the value of n is larger, the same thing (PI's approximation accuracy is not elevated) will still occur. Fortunately, there are more than one way to uncover the mystery. Using the Python decimal (decimal) library, we can get a higher-precision value to approximate pi. Let's take a look at how the library functions are used. This simplified version can get more than 11 digits of the usual case of small python floating-point numbers given the precision. Here is an example of the Python Decimal library:
Wpid-python_decimal_example-2013-05-28-12-54.png
See these numbers. Wrong! We entered only 3.14, why did we get some rubbish (junk)? This is memory garbage (memory junk). To put it simply, Python gives you the decimal number you want, plus a little extra value. As long as the precision is less than the garbage count, it does not affect any calculations. By setting GetContext (). Prec you can get the number of digits you want. Let's try it.
See these numbers. Wrong! We entered only 3.14, why did we get some rubbish (junk)? This is memory garbage (memory junk). To put it simply, Python gives you the decimal number you want, plus a little extra value. As long as the precision is less than the garbage count, it does not affect any calculations. By setting GetContext (). Prec you can get the number of digits you want. Let's try it.
Very good. Now let's try this to see if we can get a better approximation of our previous code. Now, I'm usually opposed to using "from library import *", but in this case it makes the code look prettier.
Importsys
importmath
fromdecimalimport*
defmain (argv): Iflen (argv
)!=1: Sys.exit
(' Usage: calc_pi.py <n> ')
print ' \ncomputing pi v.01\n '
a=decimal (1.0)
B=decimal (1.0/MATH.SQRT (2))
t= Decimal (1.0)/decimal (4.0)
P=decimal (1.0)
foriinrange (int (sys.argv[1))):
At=decimal ((a+b)/2)
Bt=decimal (Math.sqrt (a*b))
Tt=decimal (t-p* (a-at) **2)
pt=decimal (2*p)
a=at;b=bt;t=tt;p=pt
my_pi= (a+b) **2/(4*t)
accuracy=100* (Decimal (Math.PI)-my_pi)/my_pi
print "PI is approximately:" +str (MY_PI)
Print "Accuracy with Math.PI:" +str (accuracy)
if__name__== "__main__":
Main (sys.argv[1:])
Output results:
All right. We were more accurate, but there seemed to be some rounding. from n = 100 and n = 1000, we have the same precision. Now what? OK, now let's turn to the formula. So far, the way we calculate pi is by adding a few parts together. I found some code in Dan's article on calculating Pi. He suggested that we use the following 3 formulas:
Bailey–borwein–plouffe formula
Bellard's formula
Chudnovsky algorithm
Let's start with the Bailey–borwein–plouffe formula. It looks like this:
In the code we can write it this way:
Import sys
import math from
decimal import *
def BBP (n):
pi=decimal (0)
k=0 while
K < n:
pi+= (Decimal (1)/(16**K)) * ((Decimal (4)/(8*k+1))-(Decimal (2)/(8*K+4))-(Decimal (1)/(8*K+5))-(Decimal (1)/(8*K+6))
k+=1 return
pi
def Main (argv):
If Len (argv)!=2:
sys.exit (' Usage:BaileyBorweinPlouffe.py <prec> <n> ')
getcontext (). prec= (int (sys.argv[1))
my_pi=bbp (int (sys.argv[2)
) accuracy=100* (Decimal (Math.PI)-my_pi)/my_pi
print "PI is approximately" +str (MY_PI)
print "accuracy with Math.PI: "+str (accuracy)
if __name__==" __main__ ":
Main (sys.argv[1:])
By throwing away the "packaging" code, the BBP (N) feature is what you really want. You give it the larger N and give GetContext (). The larger the PREC setting, the more accurate the calculation will be. Let's take a look at some code results:
This has many digits. You can see that we are not more accurate than before. So we need to go forward to the next formula, Beira formula, hoping to get better accuracy. It looks like this:
We will only change our transformation formula and the rest of the code will remain unchanged. Click here to download the Beira formula implemented by Python. Let's take a look at Bellards (n):
def bellard (n):
pi=decimal (0)
k=0 while
K < n:
pi+= (Decimal ( -1) **k/(1024**k)) * (Decimal (256)/(10 *k+1) +decimal (1)/(10*k+9)-decimal (+)/(10*k+3)-decimal (+)/(4*k+1)-decimal (4)/(10*K+5)-decimal (4)/(10*K+7)- Decimal (1)/(4*k+3))
k+=1
pi=pi*1/(2**6) return
pi
Oh, no, we're getting the same precision. Well, let's try the third formula, the Chudnovsky algorithm, which looks like this:
Again, let's take a look at the formula (assuming we have a factorial formula). Click here to download the Chudnovsky formula implemented in Python.
The following are the program and output results:
def Chudnovsky (n):
pi=decimal (0)
k=0 while
K < n:
pi+= (Decimal ( -1) **k) * (Decimal (factorial (6*k)) /((factorial (k) **3) * (factorial (3*k)) * (13591409+545140134*k)/(640320** (3*k)))
k+=1
pi=pi*decimal (10005 ). sqrt ()/4270934400
pi=pi** ( -1) return
pi
So, what do we have to conclude? Fancy algorithms do not make the machine floating-point world reach a higher standard. I'm really looking forward to having a better accuracy than we can get with the sum formula. I guess that's too much to ask. If you really need to use PI, just use the Math.PI variable. However, as fun and testing how fast your computer can really be, you can always try the first one to calculate the number of pi or more digits.