Как преобразовать специальный float в дробный объект - PullRequest
0 голосов
/ 20 октября 2010

У меня есть эта функция внутри другой функции:

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 сообщает об этой ошибке:

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

Как я могу конвертировать числов этой форме в объект фракции?

Есть ли лучшее решение, чем:

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

Спасибо,
rubik

PS bin_coeff всегда возвращает число с плавающей запятой

Ответы [ 2 ]

1 голос
/ 20 октября 2010

Если вам интересно, это связано (как и следовало ожидать) с регулярным выражением Fraction в fractions.py:

_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 голос
/ 20 октября 2010

Я не могу воспроизвести вашу ошибку в py3k, но вы можете передать свой float прямо в from_float метод класса:

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