Pi - Wikipedia π
fast "PI" calculation is now possible thanks to (relatively) new algorithm
and languages as Python and now JavaScript that support "unlimited" digits numbers
Pi - Rosetta Code, in many programming languages
cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf
Unbounded Spigot Algorithms for the Digits of Pi
Jeremy Gibbons
PY: pi digits: 10000 time: 11.72525 sec
JS: PiGen digits: 10000 time: 26.08004309999943 sec
C#: Pi digits: 10000 time: 15.902 sec
Go: GenPiA digits: 10000 time: 6.1173453s
BigInt - JavaScript | MDN
BigIntBigInt
is a special numeric type that provides support for integers of arbitrary length.
BigInt | Can I use... Support tables for HTML5, CSS3, etc
BigInt numbers in JavaScript have "n" suffix when assigned
JavaScript
function* genPi() {
var [q, r, t, k, n, l, nn, nr] = [1n, 0n, 1n, 1n, 3n, 3n, 0n, 0n]
while (true) {
if (4n * q + r - t < n * t) {
yield n
nr = 10n * (r - n * t)
n = (10n * (3n * q + r)) / t - 10n * n
q *= 10n
r = nr
} else {
nr = (2n * q + r) * l
nn = (q * (7n * k) + 2n + (r * l)) / (t * l)
q *= k
t *= l
l += 2n
k += 1n
n = nn
r = nr
}
}
}
const pi = genPi();
for (var i = 0; i < 1000; i++) {
console.log(pi.next().value.toString());
}
Pi - Rosetta Code: Python
def gen_pi():
q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
while True:
if 4*q+r-t < n*t:
yield n
nr = 10*(r-n*t)
n = ((10*(3*q+r))//t)-10*n
q *= 10
r = nr
else:
nr = (2*q+r)*l
nn = (q*(7*k)+2+(r*l))//(t*l)
q *= k
t *= l
l += 2
k += 1
n = nn
r = nr
count = 0
for d in gen_pi():
sys.stdout.write(str(d))
count += 1
if count >= 1000:
break
3141592653589793238462643383279502884197
1693993751058209749445923078164062862089
9862803482534211706798214808651328230664
7093844609550582231725359408128481117450
2841027019385211055596446229489549303819
6442881097566593344612847564823378678316
5271201909145648566923460348610454326648
2133936072602491412737245870066063155881
7488152092096282925409171536436789259036
0011330530548820466521384146951941511609
4330572703657595919530921861173819326117
...
C# (dotnet)
public static IEnumerable<BigInteger> GenPiDigits()
{
BigInteger b1 = BigInteger.One, b2 = new BigInteger(2), b3 = new BigInteger(3),
b4 = new BigInteger(4), b7 = new BigInteger(7), b10 = new BigInteger(10),
k = b1, l = b3, n = b3, q = b1, r = BigInteger.Zero, t = b1, nn, nr;
while (true)
{
if ((b4 * q + r - t).CompareTo(n * t) == -1)
{
yield return n;
nr = b10 * (r - (n * t));
n = b10 * (b3 * q + r) / t - (b10 * n);
q *= b10;
r = nr;
}
else
{
nr = (b2 * q + r) * l;
nn = (q * (b7 * k) + b2 + r * l) / (t * l);
q *= k;
t *= l;
l += b2;
k += b1;
n = nn;
r = nr;
}
}
}
int i = 0;
foreach (var n in Algorithms.GenPiDigits())
{
Console.Write(n.ToString());
if (i++ > 1000) break;
}
GoLang
import (
"math/big" // https://pkg.go.dev/math/big#Int
)
// returns an array (slice) of "max" digits of pi
// the BitInt lib has specific syntax that makes code more complex; it is fast though :)
func GenPiA(max int) []int {
_1, _2, _3, _4, _7, _10 := big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4), big.NewInt(7), big.NewInt(10)
q, r, t, k, n, l, nn, nr := big.NewInt(1), big.NewInt(0), big.NewInt(1), big.NewInt(1), big.NewInt(3), big.NewInt(3), big.NewInt(0), big.NewInt(0)
_x, _y := new(big.Int), new(big.Int)
i := 0
var digits []int = make([]int, max)
for {
// if (4n * q + r - t < n * t) {
if _x.Mul(_4, q).Add(_x, r).Sub(_x, t).Cmp(_y.Mul(n, t)) == -1 {
digits[i] = int(n.Int64())
i += 1
if i >= max {
return digits
}
// nr = 10n * (r - n * t)
nr.Mul(_10, _x.Sub(r, _y.Mul(n, t)))
// n = (10n * (3n * q + r)) / t - 10n * n
n.Mul(_3, q).Add(n, r).Mul(n, _10).Div(n, t).Sub(n, _y.Mul(_10, n))
q.Mul(q, _10) // q *= 10n
r.Set(nr) // r = nr
} else {
// nr = (2n * q + r) * l
nr.Mul(_x.Add(_y.Mul(_2, q), r), l)
// nn = (q * (7n * k) + 2n + (r * l)) / (t * l)
nn.Mul(_7, k).Mul(nn, q).Add(nn, _2).Add(nn, _x.Mul(r, l)).Div(nn, _y.Mul(t, l))
q.Mul(q, k) // q *= k
t.Mul(t, l) // t *= l
l.Add(l, _2) // l += 2n
k.Add(k, _1) // k += 1n
n.Set(nn) // n = nn
r.Set(nr) // r = nr
}
}
}
Pi - Rosetta Code PicoLisp
picolisp/picolisp: PicoLisp is an open source Lisp dialect. It runs on Linux and other POSIX-compliant systems. Its most prominent features are simplicity and minimalism. @GitHub
Pi - Rosetta Code: C
Pi - Rosetta Code: Go
This algorithm is based on an unproven conjecture but successfully produces at least the first 1 million digits. Read more about it here: https://www.gavalas.dev/blog/spigot-algorithms-for-pi-in-python/
Python: less code, more time
def gospers_pi_unproven():
q, r, t, i = 1, 180, 60, 2
while True:
u, y = 3*(3*i+1)*(3*i+2), (q*(27*i-12)+5*r)//(5*t)
yield y
q, r, t, i = 10*q*i*(2*i-1), 10*u*(q*(5*i-2)+r-y*t), t*u, i+1
JavaScript
// Calculate digits of π, yields digits one by one
function* GenPi2() {
let q = 1n, r = 180n, t = 60n
for (let i = 2n; ; i += 1n) {
let y = (q * (27n * i - 12n) + 5n * r) / (5n * t)
let u = 3n * (3n * i + 1n) * (3n * i + 2n)
r = 10n * u * (q * (5n * i - 2n) + r - y * t)
q = 10n * q * i * (2n * i - 1n)
t = t * u
yield Number(y)
}
}
GoLang: more code, less execution time :) Was not easy to make it work...
// returns an array (slice) of "max" digits of pi
// the BitInt lib has specific syntax that makes code much more complex; it is fast though :)
func GenPi2A(max int) []int {
_1, _2, _3, _5, _10, _12, _27 :=
big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(5), big.NewInt(10), big.NewInt(12), big.NewInt(27)
// q = 1, r = 180, t = 60, i = 2
q, r, t, i := big.NewInt(1), big.NewInt(180), big.NewInt(60), big.NewInt(2)
y, u, x := new(big.Int), new(big.Int), new(big.Int)
var digits []int = make([]int, max)
for count := 0; count < max; count++ {
// y = (q * (27 * i - 12) + 5 * r) / (5 * t) = ((27 * i - 12) * q + (5 * r)) / (5 * t)
y.Mul(_27, i).Sub(y, _12).Mul(y, q).Add(y, x.Mul(_5, r)).Div(y, x.Mul(_5, t))
// u = 3 * (3 * i + 1) * (3 * i + 2) = ((3 * i) + 1) * ((3 * i) + 2) * 3
// u.Mul(_3, i).Add(u, _1).Mul(u, _3).Mul(u, x.Mul(_3, i).Add(x, _2)) // 6 calls
u.Add(x.Mul(_3, i), _1).Mul(u, x.Add(x, _2)).Mul(u, _3) // 5 calls, better, faster
// r = 10 * u * (q * (5 * i - 2) + r - y * t) = (r - (y * t) + (5 * i - 2) * q) * 10 * u
r.Sub(r, x.Mul(y, t)).Add(r, x.Mul(_5, i).Sub(x, _2).Mul(x, q)).Mul(r, _10).Mul(r, u)
// q = 10 * q * i * (2 * i - 1)
q.Mul(_10, q).Mul(q, i).Mul(q, x.Mul(_2, i).Sub(x, _1))
// t = t * u
t.Mul(t, u)
// digits[count] = Number(y)
digits[count] = int(y.Int64())
// i += 1
i.Add(i, _1)
}
return digits
}
there is "official" competition of programming languages and algorithms, here:
pidigits (Benchmarks Game)
digits of Pi are also available online
including first 1000 digits of Pi
a very large number of digits of Pi is calculated by Google (as world record) and available as API
Google: serving the Pi (world record)
REST API to fetch 100 digits of Pi from the specified starting point
(max 1000 digits per request), example:
more info:
For JPL's highest accuracy calculations, which are for interplanetary navigation, we use 3.141592653589793 (15 digits)
The most distant spacecraft from Earth is Voyager 1. It is about 12.5 billion miles away.
... calculated circumference of the 25 billion mile diameter circle would be wrong by 1.5 inches.