【问题标题】:Best way to convert fractions.Fraction to decimal.Decimal?将fractions.Fraction转换为decimal.Decimal的最佳方法?
【发布时间】:2017-03-21 00:06:03
【问题描述】:

在 Python 中,fractions.Fractiondecimal.Decimal 标准库类的存在有助于使有理数的算术保持精确。对于不熟悉的人,举个例子说明它的帮助:

>>> 1 / 10 * 3
0.30000000000000004
>>> decimal.Decimal('1') / 10 * 3
Decimal('0.3')
>>> fractions.Fraction('1') / 10 * 3
Fraction(3, 10)

我的问题是,如果我有 Fraction,将其转换为 Decimal 的最佳方法是什么?

不幸的是,显而易见的解决方案不起作用:

>>> decimal.Decimal(fractions.Fraction(3, 10))
Traceback (most recent call last):
  ...
TypeError: conversion from Fraction to Decimal is not supported

现在我正在使用这个代码:

>>> decimal.Decimal(float(fractions.Fraction(3, 10)))
Decimal('0.299999999999999988897769753748434595763683319091796875')

现在,当我实际输出这个值时,任何数量的四舍五入都会将其转换为 0.3,并且我只在输出前立即进行此转换(所有核心数学都使用 Fraction 完成)。尽管如此,我无法从Fraction(3, 10) 获得Decimal('0.3') 对我来说似乎有点愚蠢。任何帮助将不胜感激!

【问题讨论】:

  • “在 Python 中,fractions.Fractiondecimal.Decimal 标准库类的存在有助于使有理数的算术保持精确。”不完全的。 Decimal.decimal 仍然是浮点数,它只是以 10 为底的浮点数。 Decimal(1) / Decimal(3) 无法给出准确的答案。

标签: python decimal standard-library fractions


【解决方案1】:

将分数的除法留给Decimal()自己怎么样?

def decimal_from_fraction(frac):
    return frac.numerator / decimal.Decimal(frac.denominator)

这就是Fraction.__float__() 所做的(只需将分子除以分母),但是通过将两个值中的至少一个转换为Decimal 对象,您可以控制输出。

这让您可以使用decimal 上下文:

>>> decimal_from_fraction(fractions.Fraction(3, 10))
Decimal('0.3')
>>> decimal_from_fraction(fractions.Fraction(1, 55))
Decimal('0.01818181818181818181818181818')
>>> with decimal.localcontext() as ctx:
...    ctx.prec = 4
...    decimal_from_fraction(fractions.Fraction(1, 55))
...
Decimal('0.01818')

【讨论】:

  • 类方法from_decimal支持其他方式的转换是否有原因? frac = fractions.Fraction.from_decimal(decimal.Decimal('0.3')) 有效,但Decimal 没有from_fraction 方法。
  • @roganjosh:没有标准的钩子来转换值是另一个方向,而float() 有(以__float__ 的形式)。您可以向项目提交功能请求。
  • @roganjosh: 啊,there was a feature request 但该请求从未就如何最好地实现这一点达成共识。
  • @MartijnPieters 啊,好吧,就在我正要问您是否认为考虑到您提出了一个干净的解决方法时,您是否认为这样的请求值得。我很好奇我是否遗漏了一些基本的东西,为什么不能在另一个方向干净地完成转换。感谢您的澄清:)
猜你喜欢
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 2013-01-21
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
相关资源
最近更新 更多