如何将特殊浮点数转换为分数对象

0 投票
2 回答
787 浏览
提问于 2025-04-16 05:47

我在一个函数里面有另一个函数:

def _sum(k):
        return sum([(-1) ** v * fractions.Fraction(str(bin_coeff(k, v))) * fractions.Fraction((n + v) ** m, k + 1) for v in xrange(k + 1)])

当我对 bin_coeff 使用 fractions.Fraction 时,它给我报了这个错误:

ValueError: Invalid literal for Fraction: '1.05204948186e+12'

我该如何把这种形式的浮点数转换成一个 Fraction 对象呢?

有没有比下面这个更好的解决办法:

fractions.Fraction(*bin_coeff(k, v).as_integer_ratio())

谢谢,
rubik

附注:bin_coeff 总是返回一个浮点数

2 个回答

1

如果你感兴趣的话,这个问题的原因(正如你可能猜到的)是因为在 fractions.py 文件中的 Fraction 正则表达式:

_RATIONAL_FORMAT = re.compile(r"""
    \A\s*                      # optional whitespace at the start, then
    (?P<sign>[-+]?)            # an optional sign, then
    (?=\d|\.\d)                # lookahead for digit or .digit
    (?P<num>\d*)               # numerator (possibly empty)
    (?:                        # followed by an optional
       /(?P<denom>\d+)         # / and denominator
    |                          # or
       \.(?P<decimal>\d*)      # decimal point and fractional part
    )?
    \s*\Z                      # and optional whitespace to finish
""", re.VERBOSE)

这个正则表达式无法匹配科学计数法表示的浮点数。在 Python 2.7 中对此进行了修改(以下内容来自 3.1 版本,因为我没有安装 2.7):

_RATIONAL_FORMAT = re.compile(r"""
    \A\s*                      # optional whitespace at the start, then
    (?P<sign>[-+]?)            # an optional sign, then
    (?=\d|\.\d)                # lookahead for digit or .digit
    (?P<num>\d*)               # numerator (possibly empty)
    (?:                        # followed by
       (?:/(?P<denom>\d+))?    # an optional denominator
    |                          # or
       (?:\.(?P<decimal>\d*))? # an optional fractional part
       (?:E(?P<exp>[-+]?\d+))? # and optional exponent
    )
    \s*\Z                      # and optional whitespace to finish
""", re.VERBOSE | re.IGNORECASE)
1

我在Python 3中无法重现你的错误,不过你可以直接把你的浮点数传给from_float这个类方法:

>>> fractions.Fraction.from_float(1.05204948186e+12)
Fraction(1052049481860, 1)

撰写回答