fractions.Fraction极限分子?

fractions.Fraction limit numerator?

fraction.Fraction.limit_denominator 存在,并找到分母小于给定最大值的最接近分数。但是没有明显的方法来限制分子

同时限制分子的最佳方法是什么? (即找到分子和分母都小于给定最大值的最接近分数。)

(目标:我需要将分子也限制为 2**32,因为 TIFF 文件将分数存储为两个无符号 32 位整数。)

粗略的方法(可能找不到真正的最接近的分数):

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

有没有更好的方法来找到最接近分母和分母都小于 2**32 的分数?

您可以使用float.as_integer_ratio()方法获取任何浮点数的分子和分母:

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

输出:

2578624833578781

编辑:

您可以尝试使用if语句来检查分子或分母是否大于2 ** 32;如果是这样,将它们中的每一个乘以一个比例并将它们四舍五入到最接近的整数:

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

你也可以翻转分数并调用limit_denominator来限制分子并再次翻转结果:

def limit_32bit_rational(f: float) -> Fraction:
    tmp = Fraction(f).limit_denominator(0xFFFF_FFFF)
    if tmp.numerator <= 0xFFFF_FFFF:
        # makes sure we don't flip if numerator is 0
        return tmp
    else:
        # flip numerator with denominator to limit the inputs numerator
        tmp = Fraction(numerator=tmp.denominator, denominator=tmp.numerator).limit_denominator(0xFFFF_FFFF)
        return Fraction(numerator=tmp.denominator, denominator=tmp.numerator)