
# sbPi.py
'''
  Calculates pi using the Salamin-Brett's Method
  https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_algorithm
  input:
     1000       0.010 secs; 10 steps
     10000      0.740 secs; 13
     50000      7.550 secs; 16
    100000     16.961 secs; 17
    500000    119.792 secs; 19
        1M    277.607 secs; 20
          see https://www.piday.org/million/
'''

import decimal
from decimal import Decimal as D, getcontext
import time
from decTrig import *


def sbPi():
  decimal.getcontext().prec += 2  
          # extra digits for intermediate steps
  a, b = 1, 1/D(2).sqrt()  
  t, p = 1/D(4), 1
  pi = None
  numSteps = 0
  while True:
    an = (a + b) / 2
    b = (a * b).sqrt()
    t -= p * (a - an)*(a - an)
    p = 2*p
    a, piPrev = an, pi
    pi = (a + b)*(a + b)/(4 * t)
    numSteps += 1
    # if calculated pi is not changing, break
    if pi == piPrev:
      print("No. steps:", numSteps)
      break
  decimal.getcontext().prec -= 2
  return +pi    # unary plus applies the new precision


d = int(input("No. dps? "))
decimal.getcontext().prec = d
startTime = time.time()
piEst = sbPi()
endTime = time.time() - startTime
printGrouped(piEst)
print(f"Elapsed time: {endTime:.3f} secs")
