实现一个功能,无需外部模块即可将浮点数从零开始转换为分数

问题描述

我承担了一项任务,即寻找一种方法来使函数尽可能精确地将浮点数转换为分数, 通过蛮力强迫,我创建了一个像这样的函数

def isclose(a,b,tolerance):
    return abs(a-b) <= tolerance


def fraction(a,factor=0,tol=0.01):
    while True:
        factor += 1
        a_rounded = int(round(a*factor))
        if isclose(a*factor,a_rounded,tol):
            break
    if factor == 1:
        return a_rounded
    else:
        return "{}/{}".format(a_rounded,factor)

是否有一种更有效的方法,而不必依赖外部模块?我无法使用模块,因为我正在尝试将其实现为没有分数库的micropython。

解决方法

我正在使用的算法是取小数,将其乘以10的幂(3.25变成25/100),将整数乘以新的分母(3 * 100),然后将其加到小数(300 + 25),然后放在分母(325/100)上。

如果您不需要简化,就足够了:

def float_to_frac(flt):
    integer,decimal = str(flt).split(".")
    denominator = 10 ** len(decimal)
    numerator = int(integer) * denominator + int(decimal)
    return f"{numerator}/{denominator}"

如果您需要简化,我知道的唯一方法是通过蛮力:

def float_to_frac(flt):
    integer,decimal = str(flt).split(".")
    denominator = 10 ** len(decimal)
    numerator = int(integer) * denominator + int(decimal)
    for factor in range(2,min(numerator,denominator) + 1):
        if (numerator // factor == numerator / factor) and (denominator // factor == denominator / factor):
            numerator /= factor
            denominator /= factor
    return f"{numerator}/{denominator}"
,

如果您不能使用python库,则可以将c库与micropython一起使用:

https://github.com/lvgl/lv_binding_micropython

请参阅有关“绑定其他C库”的部分

这里也有一些代码,如果您能够实现c代码,则可以使用一种深思熟虑的解决方案:

How to convert floats to human-readable fractions?