Python 如何将十进制数转换为分数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23344185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:47:31  来源:igfitidea点击:

How to convert a decimal number into fraction?

pythondecimalfractions

提问by user2370460

I was wondering how to convert a decimal into a fraction in its lowest form in Python.

我想知道如何在 Python 中以最低形式将小数转换为分数。

For example:

例如:

0.25  -> 1/4
0.5   -> 1/2
1.25  -> 5/4
3     -> 3/1

采纳答案by Martijn Pieters

You have two options:

您有两个选择:

  1. Use float.as_integer_ratio():

    >>> (0.25).as_integer_ratio()
    (1, 4)
    

    (as of Python 3.6, you can do the same with a decimal.Decimal()object.)

  2. Use the fractions.Fraction()type:

    >>> from fractions import Fraction
    >>> Fraction(0.25)
    Fraction(1, 4)
    
  1. 使用float.as_integer_ratio()

    >>> (0.25).as_integer_ratio()
    (1, 4)
    

    (从 Python 3.6 开始,您可以decimal.Decimal()object执行相同的操作。)

  2. 使用fractions.Fraction()类型

    >>> from fractions import Fraction
    >>> Fraction(0.25)
    Fraction(1, 4)
    

The latter has a very helpful str()conversion:

后者有一个非常有用的str()转换:

>>> str(Fraction(0.25))
'1/4'
>>> print Fraction(0.25)
1/4

Because floating point values can be imprecise, you can end up with 'weird' fractions; limit the denominator to 'simplify' the fraction somewhat, with Fraction.limit_denominator():

因为浮点值可能不精确,所以最终可能会得到“奇怪”的分数;限制分母以稍微“简化”分数,其中Fraction.limit_denominator()

>>> Fraction(0.185)
Fraction(3332663724254167, 18014398509481984)
>>> Fraction(0.185).limit_denominator()
Fraction(37, 200)

If you are using Python 2.6 still, then Fraction()doesn't yet support passing in a floatdirectly, but you cancombine the two techniques above into:

如果您仍在使用 Python 2.6,则Fraction()尚不支持float直接传入 a ,但您可以将上述两种技术组合为:

Fraction(*0.25.as_integer_ratio())

Or you can just use the Fraction.from_float()class method:

或者你可以只使用Fraction.from_float()类方法

Fraction.from_float(0.25)

which essentially does the same thing, e.g. take the integer ratio tuple and pass that in as two separate arguments.

它基本上做同样的事情,例如采用整数比率元组并将其作为两个单独的参数传递。

And a small demo with your sample values:

还有一个包含您的示例值的小演示:

>>> for f in (0.25, 0.5, 1.25, 3.0):
...     print f.as_integer_ratio()
...     print repr(Fraction(f)), Fraction(f)
... 
(1, 4)
Fraction(1, 4) 1/4
(1, 2)
Fraction(1, 2) 1/2
(5, 4)
Fraction(5, 4) 5/4
(3, 1)
Fraction(3, 1) 3

Both the fractionsmodule and the float.as_integer_ratio()method are new in Python 2.6.

无论是fractions模块和float.as_integer_ratio()方法在Python 2.6是新的。

回答by ajknzhol

from fractions import Fraction

print(Fraction(0.25))
print(Fraction(0.5))
print(Fraction(1.25))
print(Fraction(3))

#1/4
#1/2
#5/4
#3

回答by Matt Eding

To expand upon Martijn Pieters excellent answer with an additional option due to the imprecision inherent with more complex floats. For example:

由于更复杂的浮点数固有的不精确性,要扩展 Martijn Pieters 的优秀答案,并提供一个附加选项。例如:

>>> f = 0.8857097
>>> f.as_integer_ratio()
(1994440937439217, 2251799813685248)          # mathematically wrong
>>> Fraction(f)
Fraction(1994440937439217, 2251799813685248)  # same result but in a class
>>> Fraction(f).limit_denominator()
Fraction(871913, 984423)                      # still imprecise

The mathematical result desired was 8857097/10000000which can be achieved by casting to a string and then manipulating it.

所需的数学结果是8857097/10000000可以通过转换为字符串然后对其进行操作来实现。

Edited Response

编辑回复

I found a much simpler way to resolve the accuracy issue.

我找到了一种更简单的方法来解决准确性问题。

>>> Fraction(str(f))
Fraction(8857097, 10000000)

Casting as to a string also allows for accurate Decimal instances

转换为字符串还允许准确的 Decimal 实例

>>> Decimal(f).as_integer_ratio()
(1994440937439217, 2251799813685248)
>>> Decimal(str(f)).as_integer_ratio()
(8857097, 10000000)

Original Response

原始回复

def float_to_ratio(flt):
    if int(flt) == flt:        # to prevent 3.0 -> 30/10
        return int(flt), 1
    flt_str = str(flt)
    flt_split = flt_str.split('.')
    numerator = int(''.join(flt_split))
    denominator = 10 ** len(flt_split[1])
    return numerator, denominator

Now let's test it:

现在让我们测试一下:

>>> float_to_ratio(f)
(8857097, 10000000)      # mathematically correct

I will note that this kind of fraction precision is not optimized and will usually not be needed, but for completeness it is here. This function doesn't simplify the fraction, but you can do additional processing to reduce it:

我会注意到这种分数精度没有优化,通常不需要,但为了完整性,它在这里。这个函数不会简化分数,但你可以做额外的处理来减少它:

>>> n = 0.5
>>> float_to_ratio(n)
(5, 10)
>>> Fraction(*float_to_ratio(n))
Fraction(1, 2)

回答by The Aelfinn

If you'd like to print a proper fraction, this little recipe should do:

如果你想打印一个适当的分数,这个小食谱应该做:

from fractions import Fraction    

def dec_to_proper_frac(dec):
    sign = "-" if dec < 0 else ""
    frac = Fraction(abs(dec))
    return (f"{sign}{frac.numerator // frac.denominator} "
            f"{frac.numerator % frac.denominator}/{frac.denominator}")

This will print as follows:

这将打印如下:

>>> dec_to_proper_frac(3.75)
>>> "3 3/4"