Hello, world! A couple of days ago, I was surfing the net and saw this scary formula...
๐ณ๐ณ๐ณ
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:
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:
That allows us to make an approximation for any large N
:
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. 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.
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:
with open("pi", mode="r", encoding="utf-8") as file:
digits = file.read().replace("\n", "")
Now, let's start to write an interesting code.
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:
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:
...
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,
return (a * a / series).quantize(d(f"1.{'0' * dp}"))
Here's the whole code:
๐๐!!!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.
Top comments (0)