Search code examples
pythonfractions

fractions.Fraction limit numerator?


fraction.Fraction.limit_denominator exists, and finds the closest fraction that has a denominator smaller than a given maximum. But there is no obvious way to limit the numerator.

What is the best way to also limit the numerator? (I.e. to find the closest fraction that has both numerator and denominator smaller than a given maximum.)

(Goal: I need to limit the numerator also to 2**32, because TIFF files store fractions as two unsigned 32-bit integers.)

A crude approach (that probably does not find the truly closest fraction):

from fractions import Fraction
def limit_32bit_rational(f: float) -> Fraction:
    ndigits = 15
    while True:
            r = Fraction.from_float(f).limit_denominator(1000000)
            if r.numerator < 2**32:
                return r
            f = round(f, ndigits)
            ndigits -= 1

Is there a better way to find the closest fraction that has nominator and denominator less than 2**32?


Solution

  • You can use the float.as_integer_ratio() method to get the numerator and denominator of any float:

    f = 2345.245624
    numerator, denominator = (f).as_integer_ratio()
    print("Numerator", numerator)
    

    Output:

    2578624833578781
    

    EDIT:

    You can try using an if statement to check if the numerator or denominator is greater than 2 ** 32; if so, multiply each of them by a scale and round them to the nearest whole numbers:

    def limit_32bit_rational(f):
        numerator, denominator = (f).as_integer_ratio()
        max_num = 2 ** 32
        if numerator > max_num or denominator > max_num:
            scale = max_num / max(numerator, denominator)
            return round(numerator * scale), round(denominator * scale)
        return numerator, denominator