Calculating Pi to million decimals in Python
Tags: python, algorithms, math, programming
Published: 2021-05-16 11:38:19

Hello, world! A couple of days ago, I was surfing the net and saw this scary formula...

![Chudnovsky](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7xeyjl2yshqhnesvdwv.jpg)

😳😳😳

**P.S.** Don't watch math videos on YouTube

...and decided to calculate the pi number. In the python `math` library, pi is stored only with the first 15 decimals. But as you could see from the title, I wanted to calculate many more characters. And I wanted to do it exactly in Python because it's my favorite programming language💗. I've decided to use this ↗️ formula (it was deduced by Chudnovsky). But there're lots of factorials (it's hard to calculate them for computer) and very big numbers (it's hard to store them for computer). That's why I've started to look for the other formula for pi calculation. I've found these:

![1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/116vh88rb34wzd27wd1d.jpg)

![2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f934svhycqrkqtzsxcka.png)

![3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g95iga3l5xy5j4fevmoq.png)

But I thought that I can find something better... **and I was right**. I found this brilliant formula. It was deduced exactly for computer calculations. Here it is:

![AGM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7vc33rhvmq61oe7uft9.png)

That allows us to make an approximation for any large `N`:
 
![equation (5)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irxgl86ijm5malwkll5x.png) 

It's the AGM (Arithmetic-Geometric Mean) formula. And at first glance, there is nothing understandable here, and at second glance too, but I have already written above that this formula was specifically derived for computer calculations. That is why it is not right to present it as a mathematical formula. I will show you my code a little bit later. 

In the meantime, let's ask ourselves the following question: how can we check the accuracy of our calculations? After all, we can't know for sure if we've solved the problem correctly if we don't have the answers. So, [here](https://www.mit.edu/afs.new/sipb/contrib/pi/pi-billion.txt). I found the first billion decimal places of pi. I've trunked this file to million decimals and copied it to IDE. Now, we are ready to write some code.

# 😎😎...WRITING SOME CODE...💪🤘

First, we need a library for working with numbers with a veeery large number of decimal places. So, python has a built-in library for such purposes.

```python
from decimal import Decimal as d, getcontext as gc
```

`Decimal` is a special data type for big numbers and we need `getcontext().prec` to set the precision of our calculations. Then, we get the right pi digits:

```python
with open("pi", mode="r", encoding="utf-8") as file:
    digits = file.read().replace("\n", "")
```

Now, let's start to write an interesting code.

```python
def calc_pi(dp):
    gc().prec = dp + 3  # Set the precision
    a, n, g, series = d(1), d(1), 1 / d(2).sqrt(), d(.25)  # Set start values
    ...
```

Then, let's change the values of the variables while the number is wrong:

```python
while (a * a / series).quantize(d(f"1.{'0' * dp}")) != d(digits).quantize(d(f"1.{'0' * dp}")):
    ...
```

`Decimal.quantize(Decimal("1.0000..."))` is a function for rounding `Decimal` numbers. `a * a / series` is our answer.

Now, let's make the main calculations:

```python
...
series -= (a - g) * (a - g) * d(.25) * n  # Calculating denominator
n += n  # Instead of calculation 2 ** (k + 1) we just double this value
a, g = ((a + g) * d(.5), (a * g).sqrt())  # Update AGM values
```

And then,

```python
return (a * a / series).quantize(d(f"1.{'0' * dp}"))
```

Here's the whole code:

{% gist https://gist.github.com/puzzled-dev/f47c3c4028d65cde89221955c3921140 %}

# 🌟🏆!!!CONGRATULATIONS!!!🏆🌟

Yeah, we did it! If you have misunderstood smth, just ask your question in the comments. Good luck. Bye!

### P.S. And what about results?

This code calculates the first 5000 decimals in half of a second (yeah, not bad!). And the first 100000 in 15 seconds. But what about one million decimals? Yes, it's possible to calculate them in a couple of hours on my machine.