如何将特殊浮点数转换为分数对象
我在一个函数里面有另一个函数:
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)