Everyone must have heard of Pi, the irrational number that never ends. It goes by this :

`3.14159265...`

I have been learning about Pi since I was in 8th grade. All the time in school, I was curious about to which Pi extends.

Now, I know the extend – **Infinity** :P. I dedicated my precious Christmas vacation for finding the useless value of Pi.

Why ? Curiosity. Simply, the curiosity made me want to do this. Besides, it’s always fun to do something interesting.

The source code is on GitHub. Please Star it. Math Enthusiasts, fork it. 😉

## Findings

1 Million digits and 5 Million digits were successfully found. You can see them here.

The current World Record is **> 1 Trillion digits**. (I should get a super computer soon).

## Equation

Craig Wood has made a **Python** script to calculate N digits of Pi. It’s a very complicated script and it took me 2 days to understand it.

What I did is, create the client side and a **WebSocket** server. The Pi calculation is ran through Python and inserted to the database.

It’s a Live process. Meaning, a person on the client can see the step where the Pi is being calculated. If we look at the **Python** script :

```
import math
import os
import time
import MySQLdb
import base64
import zlib
import sys
digits_to_calculate = int(sys.argv[1])
db = MySQLdb.connect(host=os.environ["OPENSHIFT_MYSQL_DB_HOST"], # your host, usually localhost
user=os.environ["OPENSHIFT_MYSQL_DB_USERNAME"], # your username
passwd=os.environ["OPENSHIFT_MYSQL_DB_PASSWORD"], # your password
db="ws")
cur = db.cursor()
# The time when program start
START_TIME = time.time()
cur.execute("""
UPDATE `pi` SET `value` = %s WHERE `key_name` = %s
""", (START_TIME, "start"))
def output(name, content):
cur.execute("UPDATE `pi` SET `value` = %s WHERE `key_name` = %s", (content, name))
db.commit()
sq_i = 1
def sqrt(n, one):
global sq_i
"""
Return the square root of n as a fixed point number with the one
passed in. It uses a second order Newton-Raphson convergence. This
doubles the number of significant figures on each iteration.
"""
# Use floating point arithmetic to make an initial guess
floating_point_precision = 10**16
output("status", "sqrt," + str(sq_i))
n_float = float((n * floating_point_precision) // one) / floating_point_precision
x = (int(floating_point_precision * math.sqrt(n_float)) * one) // floating_point_precision
n_one = n * one
while 1:
sq_i+=1
output("status", "sqrt," + str(sq_i))
x_old = x
x = (x + n_one // x) // 2
if x == x_old:
break
return x
i = 0
Qab = 0
def pi_chudnovsky_bs(digits):
global i
"""
Compute int(pi * 10**digits)
This is done using Chudnovsky's series with binary splitting
"""
output("status", "init,1")
one = 10**digits
output("status", "init,2")
sqrtC = sqrt(10005*one, one)
output("status", "init,3")
C = 640320
C3_OVER_24 = C**3 // 24
def bs(a, b):
global i, Qab
"""
Computes the terms for binary splitting the Chudnovsky infinite series
a(a) = +/- (13591409 + 545140134*a)
p(a) = (6*a-5)*(2*a-1)*(6*a-1)
b(a) = 1
q(a) = a*a*a*C3_OVER_24
returns P(a,b), Q(a,b) and T(a,b)
"""
"""
Subin Siby <subinsb.com>
"""
if i != 0 and i != 1:
calculated_digits = str(digits - (digits/i) + 7)
output("status", "pi," + str(i) + "," +calculated_digits + "," + str(digits_to_calculate))
"""
Calculate
"""
if b - a == 1:
# Directly compute P(a,a+1), Q(a,a+1) and T(a,a+1)
if a == 0:
Pab = Qab = 1
else:
Pab = (6*a-5)*(2*a-1)*(6*a-1)
Qab = a*a*a*C3_OVER_24
Tab = Pab * (13591409 + 545140134*a) # a(a) * p(a)
if a & 1:
Tab = -Tab
else:
# Recursively compute P(a,b), Q(a,b) and T(a,b)
# m is the midpoint of a and b
m = (a + b) // 2
# Recursively calculate P(a,m), Q(a,m) and T(a,m)
Pam, Qam, Tam = bs(a, m)
# Recursively calculate P(m,b), Q(m,b) and T(m,b)
Pmb, Qmb, Tmb = bs(m, b)
# Now combine
Pab = Pam * Pmb
Qab = Qam * Qmb
Tab = Qmb * Tam + Pam * Tmb
i+=1
return Pab, Qab, Tab
# how many terms to compute
DIGITS_PER_TERM = math.log10(C3_OVER_24/6/2/6)
N = int(digits/DIGITS_PER_TERM + 1)
# Calclate P(0,N) and Q(0,N)
P, Q, S = bs(0, N)
return Q*426880*sqrtC // S
pi = pi_chudnovsky_bs(digits_to_calculate)
# Compress Pi
pi = zlib.compress(str(pi))
# Save to DB
output("pi", pi)
db.close()
```

we can see the call of function **output**. This function updates the respective values in DB. The “status” key holds the current status of Pi calculation. It may have values like :

```
<td>
<h2>
<a href="#stage"><span id="stage">Stage</span></a>
</h2>
</td>
```

```
<td>
The initialization stage. Creation of variable etc.
</td>
```

```
<td>
The loop inside sqrt() function. I indicates the current iteration value.
</td>
```

```
<td>
The loop inside bs() function.<br /> I indicates the current iteration value.<br /> C indicates the number of calculated digits (most likely inaccurate)<br /> D indicates the number of digits to be calculated
</td>
```

## Status |

init,[I] |

sqrt,[I] |

pi,[I],[C],[D] |

The [I], [C], [D] above indicates an integer starting from 1.

## Technical Spec

This was also an experiment of **WebSocket**. It was a test of Live result obtaining using WebSocket.

The server is “ws-subins.rhcloud.com” using the Francium DiffSocket library. You can see “ws-subins.rhcloud.com” shows a blank page as the WebSocket server is running. Server :

```
PHP 5.4.4
Python 2.6.6
MySQL 5.5.45
```

When someone requests for the full value of Pi, sending 5 MB file (5 Million digits) to client is quite a task. But, WebSocket handles it well.

## Conclusion

The record is **> 1 Trillion** digits. It will surely require a super computer to calculate that much digits. I can see the processor load in my system when just calculating 1 Million digits.

If someone could get me a super computer, we could break the record 😉