import decimal


def calc_pi(maxK=1, prec=10, disp=11):
    """
    parameter defaults chosen to gain 1000+ digits within a few seconds
    
    Chudnovsky algorithm :
        https://en.wikipedia.org/wiki/Chudnovsky_algorithm
    
    :param maxK: 迭代次数
    :param prec: precision (for use in rounding, division, square roots..)
    :param disp: 显示小数位数
    :return: π
    """
    decimal.getcontext().prec = prec
    # k=0时，初始值
    K, M, L, X, S = 6, 1, 13591409, 1, 13591409
    for k in range(1, maxK + 1):
        # 参考化简公式计算，k+1值与k值的递归关系
        L += 545140134
        X *= -262537412640768000
        M = (K ** 3 - 16 * K) * M // k ** 3
        
        S += decimal.Decimal(M * L) / X
        K += 12
    C = 426880 * decimal.Decimal(10005).sqrt()
    pi = C / S
    print(pi)
    # drop few digits of precision for accuracy
    pi = decimal.Decimal(str(pi)[:disp])
    print("PI(", " maxK=%d iterations" % maxK,
          " decimal.getcontext().prec=%d" % prec,
          " disp=%d digits" % disp,
          " )",
          " = %s" % pi, sep='\n')
    return pi