简体   繁体   English

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

[英]How to convert a decimal number into fraction?

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

You have two options: 您有两种选择:

  1. Use float.as_integer_ratio() : 使用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 .) (从Python 3.6开始,你可以decimal.Decimal()对象做同样的decimal.Decimal() 。)

  2. Use the fractions.Fraction() type : 使用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.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 float directly, but you can combine the two techniques above into: 如果你仍在使用Python 2.6,那么Fraction()还不支持直接传入float ,但你可以将上面的两种技术结合到:

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, eg 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 fractions module and the float.as_integer_ratio() method are new in Python 2.6. fractions模块和float.as_integer_ratio()方法都是Python 2.6中的新方法。

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

To expand upon Martijn Pieters excellent answer with an additional option due to the imprecision inherent with more complex floats. 由于更复杂的花车固有的不精确性,扩展了Martijn Pieters的优秀答案并提供了额外的选择。 For example: 例如:

>>> 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/10000000 which 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)

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"

One of the easiest way is to use as_integer_ratio() like this.最简单的方法之一是像这样使用as_integer_ratio()

 b = 0.125 b.as_integer_ratio() # Output as Tuple(1, 8).Numerator as 1 & Denominator as 8

This is how to do it simple and properly.这就是如何简单而正确地做到这一点。

By using Fraction:通过使用分数:

from fractions import Fraction
decimals = [0.25, 0.5, 1.25, 3, 0.6, 0.84]

for d in decimals:
    print(Fraction(str(d))) #Cast as string for proper fraction

By using Decimal:通过使用十进制:

from  decimal import Decimal
decimals = [0.25, 0.5, 1.25, 3, 0.6, 0.84]

for d in decimals:
    d = Decimal(str(d)) #Cast as string for proper fraction
    nominator,denominator = d.as_integer_ratio()
    if denominator==1:
        print(a)
    else:
        print(nominator,denominator, sep="/")

Output:输出:

1/4
1/2
5/4
3
3/5
21/25

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM