Search code examples
pythonpython-3.xfractions

Floating point number needs to be displayed as a fraction


Request you to suggest regarding the below problem.

First we have to divide a numerator by the denominator in order to obtain a floating point number. Then the digits after the decimal needs to be displayed as a fraction.

When 9 is divided by 4 it has to be displayed as 2 1/4.This is working fine.

When 13 is divided by 5 it needs to be displayed as 2 3/5.

My code is not working for the second case. Getting output as

2 5404319552844595/9007199254740992.

STEP1: Divided the numerator by the denominator to find the quotient Calculated the remainder using (nmr%dnr).

STEP 2: Divided the remainder obtained the in above step by the denominator again. Converted the floating point number into fractions by using the Fractions built in method.

STEP 3:
The output is stored in a tuple and the output is printed. t1=(int(q),r).

Code:

from fractions import Fraction

def printValue(num,den):
    rem=0.0;q=0.0;

    q=float(num)/float(den)
    rem=float(num)%float(den)

    if rem>0:
        #print ("%0.2f"%(rem/den))
        r=Fraction(round(rem/den,2))
        t1=(int(q),r)                    #Output is stored in a tuple
        return t1
    else:
        t2=(int(q),)
        return t2


num=int(input())
den=int(input())
z=printValue(num,den)
for i in z:
    print(i,end=" ")

Solution

  • The problem is that floating point is broken... or more exactly it has a limited accuracy. A fractional number can only be exactly represented if its denominator is a power of 2, which explains that 9/4 gives the exact and expected result.

    But Python is great. The Fraction class has a limit_denominator() method which helps in finding a reasonable fractional approximation of a floating point by searching a limited denominator (by default 1000000).

    Demo:

    >>> f = 3/5
    >>> Fraction(f)
    Fraction(5404319552844595, 9007199254740992)
    >>> Fraction(f).limit_denominator()
    Fraction(3, 5)