Why Not Just Use Math.PI?
Every programming language gives you π built in. Python has
math.pi. JavaScript has Math.PI. So what’s the problem?
The problem is precision — or rather, the lack of it.
Math.PI and math.pi both give you
15–16 significant decimal digits of π:
For our randomness test, we needed 600 digits — 40× more than what the built-in constant can provide.
A 64-bit “double” (the standard in C, Java, JavaScript, Python’s
float) stores a number as: 1 sign bit + 11 exponent bits
+ 52 mantissa bits. Those 52 bits give you about
15–16 significant decimal digits — no matter what number you
store. π has infinitely many non-repeating decimal digits, so after position 16
the double just… stops. It has no more bits to spend.
Getting 600 digits requires a completely different approach: either a library that
uses arbitrary-precision arithmetic (Python’s mpmath),
or implementing a formula that works in pure integers and never touches
floating-point at all (JavaScript’s BigInt).
The Math Behind It — Machin’s Formula
You’ve already seen the key ingredient in BC Calculus: the Taylor series for arctangent. Machin’s stroke of genius in 1706 was finding a clever way to make that series converge fast enough to be practical.
a) The arctangent Taylor Series
From BC Calc, you know that many functions can be written as infinite polynomials. The arctangent function has this Taylor series:
The special value we care about: arctan(1) = π/4,
because tan(π/4) = 1.
So π = 4 · arctan(1).
The problem? Plugging x = 1 into the series means each term
is only 1/3 smaller than the last — you’d need thousands of terms for 600 digits.
b) Machin’s Formula (1706)
John Machin discovered this algebraic identity:
mpmath library uses the
AGM (Arithmetic-Geometric Mean) algorithm, which converges
quadratically — doubling the number of correct digits with each
iteration. For millions of digits, AGM is far more efficient than Machin.
But Machin is conceptually accessible and is exactly what the JavaScript
version implements.
Python Version — mpmath
The Python approach is the “library” solution: tell mpmath how many
decimal places you want, ask for mpmath.pi, and convert the result to a list of
digits. The library handles all the advanced arithmetic internally.
-
Google Colab
—
mpmathis already installed. Paste into a code cell and press Shift+Enter. -
Repl.it
— create a new Python repl, paste, run. Install
mpmathonce withpip install mpmathin the Shell tab.
JavaScript Version — BigInt + Machin’s Formula
The JavaScript approach implements Machin’s formula directly, using BigInt for exact integer arithmetic. No library needed — this runs in any modern browser console or Node.js. It’s longer than the Python version, but every step maps directly to the calculus you already know.
Count: 600 and
First 10: [1, 4, 1, 5, 9, 2, 6, 5, 3, 5] printed to the console,
followed by the 600 comma-separated digits ready to paste into the
Loaded Dice Analyzer.
BigInt type (introduced in ES2020) stores integers of
arbitrary size — no upper limit. BigInt literals are written with an
n suffix: 1n, 5n, 239n,
10n**620n. BigInt arithmetic is always exact; unlike floating-point,
it never rounds. That’s the property we need to guarantee 600 correct digits.
Two Approaches, One Answer
Python asks a library to do the hard work. JavaScript builds the formula from scratch. Both produce identical digits. Which should you use? It depends on what you want to learn.
Python — mpmath |
JavaScript — BigInt |
|
|---|---|---|
| Approach | Library does the work (AGM algorithm) | You implement Machin’s formula |
| Precision limit | Unlimited — set mp.dps to any value |
Unlimited — BigInt integers grow as needed |
| Lines of code | ~20 (excluding comments) | ~60 (excluding comments) |
| Educational value | See the big picture; trust the library | Understand the math; every step is visible |
| Where to run | Python 3, Google Colab, IDLE | Browser console (F12), Node.js |
The Sanity Check — Do Your Results Agree?
Both functions should produce exactly the same 600-digit sequence. Run both and compare the first ten digits:
If the Python and JavaScript outputs agree to all 600 digits, you have strong evidence that both implementations are correct — two completely different algorithms, two completely different languages, one answer. That kind of cross-verification is exactly how mathematicians and engineers build confidence in results that can’t be checked by hand.
Once you have the 600-digit sequence, paste it into the Loaded Dice Analyzer (model 0–9, 600 rolls) and run all four randomness tests. Pi’s digits look random — but can they fool four statistical tests? That’s the question the Analyzing Random Integers guide explores.