OverflowError: long int trop grand pour se convertir à flotter en python
j'ai essayé de calculer la distribution de poisson en python comme suit:
p = math.pow(3,idx)
depart = math.exp(-3) * p
depart = depart / math.factorial(idx)
idx varie de 0
Mais je suis d' OverflowError: long int too large to convert to float
j'ai essayé de convertir départ enfloat
mais pas de résultats.
4 réponses
Factorielles obtenir grand rapide:
>>> math.factorial(170)
7257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000L
Notez le L
; la factorielle de 170 est encore modulable pour un float:
>>> float(math.factorial(170))
7.257415615307999e+306
mais le prochain factoriel est trop grand:
>>> float(math.factorial(171))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float
Vous decimal
module; les calculs seront plus lents, mais le Decimal()
classe peut gérer les factorielles de cette taille:
>>> from decimal import Decimal
>>> Decimal(math.factorial(171))
Decimal('1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000')
vous devrez utiliser Decimal()
valeurs à travers:
from decimal import *
with localcontext() as ctx:
ctx.prec = 32 # desired precision
p = ctx.power(3, idx)
depart = ctx.exp(-3) * p
depart /= math.factorial(idx)
quand idx devient grand soit le math.pow
et/ou math.factorial
va devenir démesurément grand et ne pourra pas se convertir à une valeur flottante (idx=1000
déclenche l'erreur sur mon ordinateur 64 bits). Tu ne dois pas utiliser les maths.pow fonctionne car il déborde plus tôt que le construit dans **
opérateur car il essaie de garder une plus grande précision en convertissant plus tôt les flotteurs. En outre, vous pouvez envelopper chaque appel de fonction dans un Decimal
objet pour plus de précision.
une autre approche lorsque traiter de très grands nombres est de travailler dans l'échelle logarithmique. Prendre le log de chaque valeur (ou calculer la version log de chaque valeur) et effectuer toutes les opérations nécessaires avant de prendre l'exponentiation des résultats. Cela permet à vos valeurs de quitter temporairement l'espace du domaine flottant tout en calculant avec précision une réponse finale qui se trouve dans le domaine flottant.
3 ** idx => math.log(3) * idx
math.exp(-3) * p => -3 + math.log(p)
math.factorial(idx) => sum(math.log(ii) for ii in range(1, idx))
...
math.exp(result)
cela reste dans le domaine log jusqu'à la toute fin de sorte que vos nombres peuvent devenir très, très grand avant tu vas avoir des problèmes de débordement.
essayez d'utiliser la bibliothèque décimale. Il prétend en précision arbitraire.from decimal import Decimal
en outre, vous n'avez pas besoin d'utiliser math.pow
. pow
est en construction.
scipy
module pourrait vous aider.
scipy.misc.factoriel est une fonction factorielle qui peut utiliser l'approximation de la fonction gamma pour calculer le factoriel, et renvoie le résultat en utilisant des points flottants.
import numpy
from scipy.misc import factorial
i = numpy.arange(10)
print(numpy.exp(-3) * 3**i / factorial(i))
Donne:
[ 0.04978707 0.14936121 0.22404181 0.22404181 0.16803136 0.10081881
0.05040941 0.02160403 0.00810151 0.0027005 ]
Il y a aussi un module pour calculer les distributions de Poisson. Par exemple:
import numpy
from scipy.stats import poisson
i = numpy.arange(10)
p = poisson(3)
print(p.pmf(i))
Donne:
[ 0.04978707 0.14936121 0.22404181 0.22404181 0.16803136 0.10081881
0.05040941 0.02160403 0.00810151 0.0027005 ]