Операции для Long и Float в Python - PullRequest
0 голосов
/ 06 октября 2009

Я пытаюсь вычислить это:

from scipy import *
3600**3400 * (exp(-3600)) / factorial(3400)

ошибка: неподдерживаемый long и float

Ответы [ 5 ]

3 голосов
/ 06 октября 2009

Попробуйте использовать логарифмы вместо работы с числами напрямую. Поскольку ни одна из ваших операций не является сложением или вычитанием, вы можете сделать все это в форме логарифма и преобразовать обратно в конце.

2 голосов
/ 06 октября 2009

Вычисляя с числами такой величины, вы просто не можете использовать обычные 64-битные или около того числа с плавающей запятой, что поддерживает ядро ​​Python. Рассмотрим gmpy (не не получите версию sourceforge, она устарела) - с этим, math и некоторая осторожность ...:

>>> e = gmpy.mpf(math.exp(1))
>>> gmpy.mpz(3600)**3400 * (e**(-3600)) / gmpy.fac(3400)
mpf('2.37929475533825366213e-5')

(конечно, я склонен к gmpy, так как я возник и все еще участвую в этом проекте, но я никогда не буду настаивать на его способностях с плавающей точкой ... мы использовали его в основном для целочисленных вещей ... тем не менее, делает возможным это вычисление! -).

1 голос
/ 06 октября 2009

Вы можете попробовать использовать объект Десятичный . Расчеты будут выполняться медленнее, но у вас не будет проблем с очень маленькими числами.

from decimal import Decimal

Однако я не знаю, как Decimal взаимодействует с модулем scipy.

Эта дискуссия может быть актуальной.

0 голосов
/ 07 октября 2009

exp (-3600) слишком маленький, факториал (3400) слишком большой:

In [1]: from scipy import exp

In [2]: exp(-3600)
Out[2]: 0.0
In [3]: from scipy import factorial

In [4]: factorial(3400)
Out[4]: array(1.#INF)

Как насчет посчитать это шаг за шагом, как обходной путь (и это имеет смысл проверить самый маленький и самый большой промежуточный результат):

from math import exp
output = 1
smallest = 1e100
biggest = 0
for i,j in izip(xrange(1, 1701), xrange(3400, 1699, -1)):
    output = output * 3600 * exp(-3600/3400) / i
    output = output * 3600 * exp(-3600/3400) / j
    smallest = min(smallest, output)
    biggest = max(biggest, output)
print "output: ", output
print "smallest: ", smallest
print "biggest: ", biggest

вывод:

output:  2.37929475534e-005
smallest:  2.37929475534e-005
biggest:  1.28724174494e+214
0 голосов
/ 06 октября 2009

Ну, ошибка возникает потому, что вы пытаетесь умножить

3600**3400

что является длинным с

exp(-3600)

который является поплавком.

Но независимо от того, ошибка, которую вы получаете, скрывает истинную проблему. Кажется, что exp (-3600) слишком большое число, чтобы вписаться в число с плавающей точкой. В лучшем случае математическая библиотека python непостоянна с большими числами.

...