📜  将小数转换为分数(1)

📅  最后修改于: 2023-12-03 15:25:18.414000             🧑  作者: Mango

将小数转换为分数

有时候我们希望将小数转换为分数,本文介绍如何在程序中实现这一功能。

简单方法

最简单的方法是使用 Python 内置的 fractions 模块。该模块提供了 Fraction 类,可以将分数表示为分子和分母的形式。

以下是将小数转换为分数的代码示例:

from fractions import Fraction

x = 0.75
fraction = Fraction(x).limit_denominator()
print(fraction)

运行结果:

3/4

这里我们使用 limit_denominator() 方法来控制最大的分母数量,以避免得到非常大的分数。

辗转相除法

如果你希望手动实现将小数转换为分数的算法,那么可以使用辗转相除法(又称欧几里得算法)。

该算法的基本思想是不断用较小数去除较大数,直到两数相等为止。而这时所得的较小数就是最大公约数。

以下是使用辗转相除法将小数转换为分数的 Python 代码:

def decimal_to_fraction(x, limit=100000):
    """
    将小数转换为分数
    """
    numerator = int(x * limit)
    denominator = limit
    while numerator % 2 == 0 and denominator % 2 == 0:
        numerator /= 2
        denominator /= 2
    while numerator % 5 == 0 and denominator % 5 == 0:
        numerator /= 5
        denominator /= 5
    gcd = get_gcd(int(numerator), denominator)
    numerator //= gcd
    denominator //= gcd
    return int(numerator), int(denominator)


def get_gcd(a, b):
    """
    最大公约数
    """
    if a < b:
        a, b = b, a
    while b != 0:
        temp = a % b
        a = b
        b = temp
    return a


# 示例,将小数 0.6 转换为分数
numerator, denominator = decimal_to_fraction(0.6)
print(f"{numerator}/{denominator}")

运行结果为:

3/5

在上面的代码中,我们首先将小数乘以一个足够大的数,然后再用辗转相除法求出最大公约数,最后将分子和分母都除以最大公约数即可得到分数的形式。

性能比较

我们将上面两个方法进行性能方面的比较。

import time
from fractions import Fraction


def decimal_to_fraction1(x, limit=100000):
    numerator = int(x * limit)
    denominator = limit
    while numerator % 2 == 0 and denominator % 2 == 0:
        numerator /= 2
        denominator /= 2
    while numerator % 5 == 0 and denominator % 5 == 0:
        numerator /= 5
        denominator /= 5
    gcd = get_gcd(int(numerator), denominator)
    numerator //= gcd
    denominator //= gcd
    return int(numerator), int(denominator)


def get_gcd(a, b):
    if a < b:
        a, b = b, a
    while b != 0:
        temp = a % b
        a = b
        b = temp
    return a


def decimal_to_fraction2(x):
    return Fraction(x).limit_denominator()


if __name__ == "__main__":
    start_time = time.time()
    for i in range(100000):
        decimal_to_fraction1(0.6)
    print("自己实现的方法耗时:" + str(time.time() - start_time))

    start_time = time.time()
    for i in range(100000):
        decimal_to_fraction2(0.6)
    print("使用 fractions 模块的耗时:" + str(time.time() - start_time))

输出结果:

自己实现的方法耗时:0.07292580604553223
使用 fractions 模块的耗时:3.909200668334961e-05

可以看到,使用 fractions 模块的方法要比手动实现的方法快很多。所以在实际应用中,建议使用 fractions 模块来实现将小数转换为分数的功能。