implement a popular pidigitextraction algorithm known as the baileyborweinplouffe bbp formula to calculate the nth hex digit of pi wikipedia page https en wikipedia orgwikibaileye28093borweine28093plouffeformula param digitposition a positive integer representing the position of the digit to extract the digit immediately after the decimal point is located at position 1 param precision number of terms in the second summation to calculate a higher number reduces the chance of an error but increases the runtime return a hexadecimal digit representing the digit at the nth position in pi s decimal expansion joinbaileyborweinplouffei for i in range1 11 243f6a8885 baileyborweinplouffe5 10000 6 baileyborweinplouffe10 traceback most recent call last valueerror digit position must be a positive integer baileyborweinplouffe0 traceback most recent call last valueerror digit position must be a positive integer baileyborweinplouffe1 7 traceback most recent call last valueerror digit position must be a positive integer baileyborweinplouffe2 10 traceback most recent call last valueerror precision must be a nonnegative integer baileyborweinplouffe2 1 6 traceback most recent call last valueerror precision must be a nonnegative integer compute an approximation of 16 n 1 pi whose fractional part is mostly accurate return the first hex digit of the fractional part of the result only care about first digit of fractional part don t need decimal private helper function to implement the summation functionality param digitpostoextract digit position to extract param denominatoraddend added to denominator of fractions in the formula param precision same as precision in main function return floatingpoint number whose integer part is not important if the exponential term is an integer and we mod it by the denominator before dividing only the integer part of the sum will change the fractional part will not implement a popular pi digit extraction algorithm known as the bailey borwein plouffe bbp formula to calculate the nth hex digit of pi wikipedia page https en wikipedia org wiki bailey e2 80 93borwein e2 80 93plouffe_formula param digit_position a positive integer representing the position of the digit to extract the digit immediately after the decimal point is located at position 1 param precision number of terms in the second summation to calculate a higher number reduces the chance of an error but increases the runtime return a hexadecimal digit representing the digit at the nth position in pi s decimal expansion join bailey_borwein_plouffe i for i in range 1 11 243f6a8885 bailey_borwein_plouffe 5 10000 6 bailey_borwein_plouffe 10 traceback most recent call last valueerror digit position must be a positive integer bailey_borwein_plouffe 0 traceback most recent call last valueerror digit position must be a positive integer bailey_borwein_plouffe 1 7 traceback most recent call last valueerror digit position must be a positive integer bailey_borwein_plouffe 2 10 traceback most recent call last valueerror precision must be a nonnegative integer bailey_borwein_plouffe 2 1 6 traceback most recent call last valueerror precision must be a nonnegative integer compute an approximation of 16 n 1 pi whose fractional part is mostly accurate return the first hex digit of the fractional part of the result only care about first digit of fractional part don t need decimal private helper function to implement the summation functionality param digit_pos_to_extract digit position to extract param denominator_addend added to denominator of fractions in the formula param precision same as precision in main function return floating point number whose integer part is not important if the exponential term is an integer and we mod it by the denominator before dividing only the integer part of the sum will change the fractional part will not
def bailey_borwein_plouffe(digit_position: int, precision: int = 1000) -> str:
    
    if (not isinstance(digit_position, int)) or (digit_position <= 0):
        raise ValueError("Digit position must be a positive integer")
    elif (not isinstance(precision, int)) or (precision < 0):
        raise ValueError("Precision must be a nonnegative integer")

    sum_result = (
        4 * _subsum(digit_position, 1, precision)
        - 2 * _subsum(digit_position, 4, precision)
        - _subsum(digit_position, 5, precision)
        - _subsum(digit_position, 6, precision)
    )

    
    return hex(int((sum_result % 1) * 16))[2:]


def _subsum(
    digit_pos_to_extract: int, denominator_addend: int, precision: int
) -> float:
    
    
    total = 0.0
    for sum_index in range(digit_pos_to_extract + precision):
        denominator = 8 * sum_index + denominator_addend
        if sum_index < digit_pos_to_extract:
            
            
            
            exponential_term = pow(
                16, digit_pos_to_extract - 1 - sum_index, denominator
            )
        else:
            exponential_term = pow(16, digit_pos_to_extract - 1 - sum_index)
        total += exponential_term / denominator
    return total


if __name__ == "__main__":
    import doctest

    doctest.testmod()