Meet π

Calculating Pi to high precision in a web browser

Written by Guy Fernando

Last modified October 2020


Pi Spiral

Pi or π is defined as being the ratio of a circle’s circumference to its diameter. This ratio when expressed in any numerical base (radix) is an irrational number, this means the sequence of numbers generated does not ever repeat or terminate.

It is worth remembering, that any two numbers expressed as a fraction will eventually repeat or terminate. Therefore π can never be truly represented by a fraction.

Brief History of π

Approximations for the value π were known to the ancient Babylonians, Egyptians, Indians, Greeks, and Chinese. The earliest records of π date back to the Babylonians (c. 2000 BCE), they referred to π as the fraction 25/8 = 3.125, out by 0.528%. Roughly around the same time, the Egyptians were using a different fraction 256/81 = 3.160, out by 0.601%. Indian scriptures contained in the Vedic Shatapatha Brahmana book (c. 800 BCE) referred to π as 339/108 = 3.138̇̇̇̇̇̇̇̇, out by 0.086%. Approximately five hundred years later (c. 250B CE), Archimedes of Syracuse used inscribed and circumscribed polygons, and calculated π to be 22/7, out by 0.040%. This easy to remember approximation was still recently in use for performing rough calculations until the introduction of the modern electronic calculator. Zu Chongzhi a Chinese polymath (c. 500 CE) some seven hundred years later derived two approximations. The first being the same as the one Archimedes found, and later the more impressive approximation of 355/113 = 3.14159292, being accurate to seven decimal places, an incredible feat for the time.

The beginning of the European renaissance (c. 1400 CE), and the introduction of the Hindu-Arabic numeral system by Fibonacci at around the same time, paved the way for major advances in mathematics in Europe. By the late sixteenth century, European mathematicians were using infinite series equations to calculate the value of π with greater and greater precision. Since then, a variety of ingenious methods for approximating π, including the use of prime numbers, and even the use of the golden ratio have come to pass.

Online π Calculator

The online π calculator presented here is able to evaluate π up to one million decimal places using one of of the infinite series algorithms. Bear in mind the more digits selected, the longer the calculation will take to complete. Be prepared to wait around sometime when calculating π to more than 1000 digits, though this will depend on the speed of your computer, and the algorithm chosen. When the calculation completes, the result will be displayed below.

Select the required algorithm and number of digits, then click the Calculate button.




 


The process of evaluating π when using an infinite series involves a repetition of calculations, the more repetitions the better the approximation. Whether performing these calculations by hand or using a digital computer, it is obviously advantageous to arrive upon an answer with the fewest of repetitions. Some infinite series equations converge faster than others, which is another way of saying that the value is arrived upon more quickly for a given amount of repetitions or iterations.

Big 'O' Notation

In computer science, the big 'O' notation is used as a basis to quantify computational complexity. The notation applies to algorithms that are repetitive such as in a software loop construct, n being the number iterations before the loop terminates. The notation is a technique used to classify an algorithm's running time for a given number of iterations.

Madhava Algorithm

Madhava of Sangamagrama (c. 1340 – c. 1425) was an Indian mathematician, and was the first to use an infinite series to calculate π. Gottfried Wilhelm Leibniz, a German mathematician independently published the same series more than two hundred years later in 1676. As a consequence it is now known in the west as the Madhava-Leibniz series. Madhava also devised an improved series that converges more rapidly than the original series. This second equation is presented below and is identified as the Madhava algorithm.

\( \begin{aligned} \pi = \sqrt{12} \sum_{k=1}^ \infty \frac{ {(-1)}^{k+1} }{(2k - 1). 3^{k-1} } \end{aligned} \)

Digits calculated per iteration: ≅ 0.4

Computational complexity: \( \begin{aligned} O( n.log(n)^{3} ) \end{aligned} \)

The JavaScript implementation of the Madhava algorithm is shown opposite.

        
  // Madhava algorithm for calculating Pi.

  Decimal.precision = this.digits + 2;

  var pi = new Decimal(0);
  var Nk, Dk;
  var iterations = (this.digits / this.digitsPerIteration) + 2;

  for (var k = 1; k < iterations; k++) {
      // Numerator term, Nk = (-1)^(k+1)
      Nk = Decimal(-1).pow(k + 1);

      // Denominator term, Dk = (2k - 1) * 3^(k-1)
      Dk = Decimal((2 * k) - 1).times(Decimal(3).pow(k - 1));

      // Pi series partial summation.
      pi = pi.plus(Nk.div(Dk));
  }

  // Multiply by 12^0.5.
  pi = pi.times(Decimal(12).sqrt());

  // Set significant digits.
  pi = pi.toSD(this.digits);
        
      

Newton-Euler Algorithm

Isaac Newton (c. 1643 - c. 1727) was an English polymath who is widely recognised as one of the most influential scientists of all time. In 1666, Newton used a geometric construction to derive an infinite series for π. Leonhard Euler (c. 1707 - c. 1783) a Swiss polymath known to be one of the most eminent mathematicians of the 18th century improved Newton's original infinite series for π. It is this combined effort that is presented below and is identified as the Newton-Euler algorithm.

\( \begin{aligned} \frac{ \pi }{2} = \sum_{k=0}^ \infty \frac{2^{k} (k!)^{2} }{(2k + 1)!} \end{aligned} \)

Digits calculated per iteration: ≅ 0.3

Computational complexity: \( \begin{aligned} O( n.log(n)^{3} ) \end{aligned} \)

The JavaScript implementation of the Newton-Euler algorithm is shown opposite.

        
  // Newton-Euler algorithm for calculating Pi.

  Decimal.precision = this.digits + 3;

  var pi = new Decimal(0);
  var Nk, Dk;
  var iterations = (this.digits / this.digitsPerIteration) + 1;

  for (var k = 0; k < iterations; k++) {
      // Numerator term, Nk = 2^k * (k!)^2
      Nk = Decimal(2).pow(k).times(Decimal(this.factorial(k)).pow(2));

      // Denominator term, Dk = (2k + 1)!
      Dk = Decimal(this.factorial((2 * k) + 1));

      // Pi series partial summation.
      pi = pi.plus(Nk.div(Dk));
  }

  // Multiply by 2.
  pi = pi.times(2);

  // Set significant digits.
  pi = pi.toSD(this.digits);
        
      

Ramanujan Algorithm

Srinivasa Ramanujan (c. 1887 - c. 1920) was an Indian mathematician. Despite having no formal education and dying young he made substantial contributions to mathematical analysis, number theory, infinite series, and continued fractions, including solutions to mathematical problems at the time considered unsolvable. Ramanujan's series for π converges extraordinarily rapidly and forms the basis of some of the fastest algorithms currently used to calculate π. This equation is presented below and is identified as the Ramanujan algorithm.

\( \begin{aligned} \frac{1}{ \pi } = \frac{2 \sqrt{2} }{9801} \sum_{k=0}^ \infty \frac{(4k)!(1103 + 26390k)}{ (k!)^{4} 396^{4k}} \end{aligned} \)

Digits calculated per iteration: ≅ 8

Computational complexity: \( \begin{aligned} O( n.log(n)^{3} ) \end{aligned} \)

The JavaScript implementation of the Ramanujan algorithm is shown opposite.

        
  // Ramanujan algorithm for calculating Pi.

  Decimal.precision = this.digits + 2;

  var pi = new Decimal(0);
  var C, Mk, Lk, Xk;
  var iterations = (this.digits / this.digitsPerIteration) + 1;

  for (var k = 0; k < iterations; k++) {
      // Multinomial term, Mk = (4k)! / (k!)^4
      Mk = Decimal(this.factorial(4 * k)).div(Decimal(this.factorial(k)).pow(4));

      // Linear term, Lk = 1103 + 26390k
      Lk = Decimal(26390 * k).plus(1103);

      // Exponential term, Xk = 396^4k
      Xk = Decimal(396).pow(4 * k);

      // Pi series partial summation.
      pi = pi.plus(Mk.times(Lk).div(Xk));
  }

  // C = (2 * 2^0.5) / 9801
  C = Decimal(2).times(Decimal(2).sqrt()).div(9801);

  // Multiply by constant and take reciprocal.
  pi = Decimal(1).div(C.times(pi));

  // Set significant digits.
  pi = pi.toSD(this.digits);
        
      

Chudnovsky Algorithm

David Volfovich Chudnovsky (c. 1947) and Gregory Volfovich Chudnovsky (c. 1952) are American mathematicians and engineers known for their world-record mathematical calculations and developing the Chudnovsky algorithm used to calculate the digits of π with extreme precision. The Chudnovsky algorithm is based on the Ramanujan algorithm, but converges at about twice the rate. It is the Chudnovsky algorithm that has been used to calculate the world record for π to 31.4 trillion digits. This equation is presented below and is identified as the Chudnovsky algorithm.

\( \begin{aligned} \frac{426880 \sqrt{10005} }{ \pi } = \sum_{k=0}^ \infty \frac{(6k)!(545140134k + 13591409)}{(3k)! (k!)^{3} (-262537412640768000)^{k}} \end{aligned} \)

Digits calculated per iteration: ≅ 14

Computational complexity: \( \begin{aligned} O( n.log(n)^{3} ) \end{aligned} \)

The JavaScript implementation of the Chudnovsky algorithm is shown opposite.

        
  // Chudnovsky algorithm for calculating Pi.

  Decimal.precision = this.digits + 2;

  var pi = new Decimal(0);
  var C, Mk, Lk, Xk;
  var iterations = (this.digits / this.digitsPerIteration) + 1;

  for (var k = 0; k < iterations; k++) {
      // Multinomial term, Mk = (6k)! / (3k)! * (6k)!^3
      Mk = Decimal(this.factorial(6 * k)).div(Decimal(this.factorial(3 * k)).times(Decimal(this.factorial(k)).pow(3)));

      // Linear term, Lk = 545140134k + 13591409
      Lk = Decimal(545140134 * k).plus(13591409);

      // Exponential term, Xk = -262537412640768000^k
      Xk = Decimal(-262537412640768000).pow(k);

      // Pi series partial summation.
      pi = pi.plus(Mk.times(Lk).div(Xk));
  }

  // C = 1 / (426880 * 10005^0.5)
  C = Decimal(1).div(Decimal(426880).times(Decimal(10005).sqrt()));

  // Multiply by constant and take reciprocal.
  pi = Decimal(1).div(C.times(pi));

  // Set significant digits.
  pi = pi.toSD(this.digits);
        
      

Calculation Method Used Here

The calculation is performed on your computer, and in a separate web worker thread allowing this page to remain responsive and to be scrolled while the calculation is in progress.

To evaluate an approximation of π to high precision, the built-in 64-bit IEEE 754 floating point numerical system that JavaScript uses cannot be used beyond 15 decimal places. To achieve higher accuracy, an arbitrary precision numeric library such as Decimal.js is used. Decimal.js is a self contained open-source library with a large community of users. It is used to calculate all the algorithms presented in this article to a precision of up to a million decimal places.

Conclusion

All the algorithms presented in this article are infinite series, as a result computational memory requirements and execution time will be a function of the number of digits that need to be calculated. Furthermore the computer memory requirements will roughly be proportional to the number of digits required, whereas computer execution time per digit will exponentially increase as the number of digits required increases.

Incredibly, the Madhava algorithm despite being devised three centuries earlier than the Newton-Euler algorithm, actually converges around 50 times faster. The modern day algorithms, which you would expect, converge even faster.

The Ramanujan and Chudnovsky algorithms are both similar having multinomial, linear and exponential terms. Although these algorithms converge faster, they are computationally more complex and as a result will take an increasingly longer time to calculate subsequent digits. They are around 400 and 700 times faster respectively than the Newton-Euler algorithm.

Unquestionably this is not the end of the story, and surely in time new algorithms will be conceived that converge even quicker than the Chudnovsky algorithm.