Skip to content

Instantly share code, notes, and snippets.

@josephsamela
Created January 21, 2020 01:32
Show Gist options
  • Save josephsamela/6f8402ea33caa97be7e20b9ac5b918cc to your computer and use it in GitHub Desktop.
Save josephsamela/6f8402ea33caa97be7e20b9ac5b918cc to your computer and use it in GitHub Desktop.
import math
def pi_chudnovsky(one=1000000):
"""
Calculate pi using Chudnovsky's series
This calculates it in fixed point, using the value for one passed in
"""
k = 1
a_k = one
a_sum = one
b_sum = 0
C = 640320
C3_OVER_24 = C**3 // 24
while 1:
a_k *= -(6*k-5)*(2*k-1)*(6*k-1)
a_k //= k*k*k*C3_OVER_24
a_sum += a_k
b_sum += k * a_k
k += 1
if a_k == 0:
break
total = 13591409*a_sum + 545140134*b_sum
pi = (426880*sqrt(10005*one, one)*one) // total
return pi
def sqrt(n, one):
"""
Return the square root of n as a fixed point number with the one
passed in. It uses a second order Newton-Raphson convergence. This
doubles the number of significant figures on each iteration.
"""
# Use floating point arithmetic to make an initial guess
floating_point_precision = 10**16
n_float = float((n * floating_point_precision) // one) / floating_point_precision
x = (int(floating_point_precision * math.sqrt(n_float)) * one) // floating_point_precision
n_one = n * one
while 1:
x_old = x
x = (x + n_one // x) // 2
if x == x_old:
break
return x
def calc_pi_digits(d):
pi = 0
digits = 0
powers = 1
while digits < d+10: # Go +10 digits longer than requested to make sure the calculation of pi has converged at that value
pi = pi_chudnovsky(10**digits)
digits = len(str(pi))
powers *= 10
return pi
# https://www.craig-wood.com/nick/articles/pi-chudnovsky/
if __name__ == "__main__":
for i in range(100):
print(calc_pi_digits(i))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment