Nenad Savic
Nenad Savic

Reputation: 77

Overflow Error: ..long int too large

import math
a = 100
b = 110
e = 2.71828
x = (e**-a)*(a**b)/math.factorial(b)
print round(x, 5)

when a and b are large I get this message:

Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
OverflowError: long int too large to convert to float

Upvotes: 1

Views: 559

Answers (3)

JulienD
JulienD

Reputation: 7293

You seem to be trying to implement a Poisson distribution. For large values of its mean, it is very well approximated by a Gaussian distribution, for which you do not need to compute the factorial (which is way too big as others already said).

http://en.wikipedia.org/wiki/Poisson_distribution#Related_distributions

Edit: the number of events k is independant of the mean, but usually one does not want a probability such as P(200|L) for small L, or one rounds it to zero.

Also have a look at Scipy's implementation, which seems to use the logarithm, another way or avoiding very large numbers: https://github.com/scipy/scipy/blob/v0.14.0/scipy/stats/_discrete_distns.py

Edit: since it was requested, a demo in R (because it is quicker for me in my current setup, but the maths are the same). I took lambda = mean = sigma^2 = 500 (without the continuity correction for n<1000):

pois = rpois(1000, 500)
norm = rnorm(1000, 500, sqrt(500))
plot(density(pois))
lines(density(norm))

enter image description here

Upvotes: 4

0x90
0x90

Reputation: 41022

You are exceeding the max float value (1.7976931348623157e+308).

Use the decimal module:

import math
from decimal import Decimal   
a = 200
b = 198
e = 2.71828
x = Decimal(e**-a)*Decimal(a**b)/math.factorial(Decimal(b))
print round(x, 5)   

Output:

0.02806

Compare it with the output that WloframAlpha calculated 0.0280567


In case you want to see the float info, see this:

>>> import sys
>>> print  sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

Upvotes: 1

Hugo Walter
Hugo Walter

Reputation: 3168

as long as (a**b) >> math.factorial(b) you could just do

(a**b)/math.factorial(b)*(e**-a)

this way the number gets smaller before being converted to float

Upvotes: 1

Related Questions