Search code examples
pythonpython-3.6fractionsrecurring

Calculate period length of recurring decimal fraction


I want to do a program in python (3.6.5) that tell the length of e.g. 1/7. The output should be for this example something like: "length: 6, repeated numbers: 142857". I got this so far:

n = int(input("numerator: "))
d = int(input("denominator: "))

def t(n, d):
    x = n * 9
    z = x
    k = 1
    while z % d:
        z = z * 10 + x
        k += 1
        print ("length:", k)
        print ("repeated numbers:", t)

    return k, z / d

t(n, d)

Solution

  • Doing print ("repeated numbers:", t) prints the representation of the t function itself, not its output.

    Here's a repaired version of your code. I use a Python 3.6+ f-string to convert the repeating digits to a string, and add zeros to the front to make it the correct length.

    def find_period(n, d):
        z = x = n * 9
        k = 1
        while z % d:
            z = z * 10 + x
            k += 1
    
        digits = f"{z // d:0{k}}"
        return k, digits
    
    # Test
    
    num, den = 1, 7
    period, digits = find_period(num, den)
    print('num:', num, 'den:', den, 'period:', period, 'digits:', digits)
    
    num, den = 1, 17
    period, digits = find_period(num, den)
    print('num:', num, 'den:', den, 'period:', period, 'digits:', digits)
    

    output

    num: 1 den: 7 period: 6 digits: 142857
    num: 1 den: 17 period: 16 digits: 0588235294117647
    

    This line may be a bit mysterious:

    f"{z // d:0{k}}"
    

    It says: Find the largest integer less than or equal to z divided by d, convert it to a string, and pad it on the left with zeroes (if necessary) to give it a length of k.


    As Goyo points out in the comments, this algorithm is not perfect. It gets stuck in a loop if the decimal contains any non-repeating part, that is, if the denominator has any factors of 2 or 5. See if you can figure out a way to deal with that.