
Thinking back to high school you may remember being taught about pi and using it in maths classes to calculate perimeters and areas of circles. You may remember being told a good approximation of pi is 3.14
, or 22/7
. But you may also recall that pi is irrational (meaning, in maths, that it cannot be expressed exactly as a ratio of two integers; basically, writing it out, it goes on forever; there are even books you can buy listing pi to a million decimal places).
Perhaps, over the years, you have wondered how pi is calculated. I never really thought about it until my first year of university, but was quite excited to discuss it with my first year tutor and discover the rich history of this calculation. There are many ways to calculate pi, but I thought it might be fun to go over a simple, unusual, but fun way to do this, using nothing more than high school mathematics.
The Monte Carlo Method
So, first, let’s talk about the Monte Carlo Method. This is a computational technique for performing calculations using repeated random numbers. It gets its name from the famous Monte Carlo Casino, where repeated randomness is applied to get money from your wallet.
The method has many practical applications in many fields of science, but it can be applied here to calculate pi in an interesting way that is also pretty easy to understand.
An Application of Monte Carlo
Let’s step through an example using the Monte Carlo Method to calculate the value of pi.
Suppose we have a square that is \(2x\) wide and \(2x\) high (where \(x\) is some number). If you draw the largest circle to fit in that square it has a radius of \(x\), as shown:

The area of a square is the area of a side squared. So in our example, given each side is \(2x\) wide:
$$\begin{eqnarray}\text{Area of square} &=& (2x)^2\\ &=& 4x^2\end{eqnarray}$$
Remembering your high school mathematics, the area of a circle is \(\pi\) times the square of the radius. So in our example:
$$\begin{eqnarray}\text{Area of circle} &=& \pi x^2\end{eqnarray}$$
Now, we want to calculate pi.
If you randomly throw dots in the square, they will either be in the circle, or outside the circle:

As you get more and more random dots falling, the ratio:
$$\frac{\text{Number dots in circle}}{\text{Number of dots in square}}$$
Should approach the same ratio as:
$$\begin{eqnarray}\frac{\text{Area of circle}}{\text{Area of square}} &=& \frac{\pi x^2}{4x^2}\\ &=& \frac{\pi}{4}\end{eqnarray}$$
So,
$$\pi = 4 \times \frac{\text{Area of circle}}{\text{Area of square}}$$
Thus, 4 times the \(\frac{\text{Number dots in the circle}}{\text{Number of dots in square}}\) should approach \(\pi\) the more random dots we drop.
An Algorithm to Calculate Pi
We can work out a simple algorithm to count these dots and thus calculate \(\pi\). Let’s say the square has \((0,0)\) in the top left, and \((2x,2x)\) in the bottom right, then in the centre is \((x, x)\).
You can tell if a dot \((a,b)\) is in the circle if the distance \(d\) from \((x,x)\) to \((a,b)\) is less than \(x\). From Pythagorus:

$$\begin{eqnarray}d^2 &=& (a-x)^2 + (b-x)^2\\d &=& \sqrt{(a-x)^2 + (b-x)^2}\end{eqnarray}$$
So, let’s take \(x = 1\). suppose we generate 2 random numbers between \(0\) and \(2x = 2\). They become our \((a, b)\). We then do this a number of times, and count up the number where \(d < 1\), versus the total (which is everything in the square). This should approach pi the more times we do this.
Calculating Pi
To show this, I wrote a small Swift script. I put this in a file called montecarlo.swift
. The script takes a command line argument (number of loops) and displays results in powers of 10 up to the total loops requested:
#!/usr/bin/swift import Foundation // Read from command line the maximum number of loops let totalloops = Int(CommandLine.arguments[1])! var loops = 1 while loops <= totalloops { var inCircle = 0 for _ in 1...loops { let (a,b) = (Double.random(in: 0.0...2.0), Double.random(in: 0.0...2.0)) let d = sqrt((a-1)*(a-1) + (b-1)*(b-1)) if d < 1.0 { inCircle += 1 } } let mypi = 4*Double(inCircle)/Double(loops) print("loops = \(loops): mypi = \(mypi)") loops *= 10 }
We run this with a command-line argument, and it shows the result of the calculation for different number of loops. The higher the number of loops, the better the approximation. Here is an example I ran on my local Terminal:
./montecarlo.swift 100000000
loops = 1: mypi = 4.0
loops = 10: mypi = 3.2
loops = 100: mypi = 3.0
loops = 1000: mypi = 3.156
loops = 10000: mypi = 3.1444
loops = 100000: mypi = 3.14464
loops = 1000000: mypi = 3.145348
loops = 10000000: mypi = 3.1416732
loops = 100000000: mypi = 3.1415698
Pi is actually 3.141592654…
, so 3.1416
is a good approximation.
This is not a particularly fast way to calculate pi (a faster method would be the Chudnovsky algorithm, for example). But it is certainly a fun and easy way to calculate pi.
Hopefully you enjoyed a little mathematical distraction from my usual posts. If there is interest I may post some other mathematics related articles in the future. Feel free to drop into the comments your own version of the script above in your favourite programming language if you feel so inclined.
Jamie
Here’s a version of the script in C64 BASIC. It is a killer to run on a C64 though as it is so slow.
10 INPUT "ENTER TOTAL LOOPS: "; T
20 LOOPS = 1
30 IF LOOPS > T THEN GOTO 200
40 INCIRCLE = 0
50 FOR I = 1 TO LOOPS
60 A = RND(0) * 2
70 B = RND(0) * 2
80 D = SQR((A-1)*(A-1) + (B-1)*(B-1))
90 IF D < 1 THEN INCIRCLE = INCIRCLE + 1
100 NEXT I
110 MYPI = 4*INCIRCLE/LOOPS
120 PRINT “LOOPS = "; LOOPS;
130 PRINT”: MYPI = ”; MYPI
140 LOOP = LOOP * 10
150 GOTO 30
200 END
Great blog Jamie, and nice touch with the C64 BASIC.
This reminds me of a project I did back in Uni WHERE BY I had to use the Icon programming language to create an infinite series of fractions that approximate pi. It used generators (think Python) and each iteration would be a closer approximation to pi.
So something like: { 22/7, 355/113, …}
I think I did it for e (i.e. 2.71828…) too