Search code examples
pythonpython-2.7mathfractions

Simplify an irrational decimal to its simple fraction equivalent using Python


Here is my problem:

I am writing a program to solve a statistical problem from timed coding challenge using Python 2.7 I'm not allowed to use many external packages ( however I can use Fractions). To finish my problem I need to convert an irrational decimal number to it's fraction equivalent.

Example Input:

0.6428571428571428 [i.e. 9/14]

Problem:

I want to output 9/14 in this instance but if I do something like:

print(Fraction(0.6428571428571428))

It will print some ungodly long fraction that can't be reduced.

Is there a way to reduce 0.6428571428571428 to 9/14 without forcing Fraction to round closest to 14 (since I need to use it for a lot of different fractions)?

Another Example:

.33333333333 (i.e. 1/3)

Current Output:

print(Fraction(.333333333333333)) # Outputs 6004799503160061/18014398509481984

Solution

  • If you know around how large your denominators get, you can use limit_denominator. See the docs for this

    Here's what you'd get setting 100000 as your denominator

    from fractions import Fraction
    print(Fraction(.333333333333333).limit_denominator(max_denominator=100000))
    # 1/3
    
    print(Fraction(0.6428571428571428).limit_denominator(max_denominator=100000))
    # 9/14
    

    We're giving plenty of freedom with 100000 as the upper limit but it still finds the result we are looking for. You can adjust that number to suit your needs.

    For these cases, I continued to get these results up to 10**14 and I start getting different results at 10**15 which is because, as Olivier Melançon points, that we have 15 digits in our input and when using max_denominator the error is 1/(2 * max_denominator)