溢出错误:long int 太大而无法在 python 中转换为浮点数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16174399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OverflowError: long int too large to convert to float in python
提问by user2312186
I tried to calculate poisson distribution in python as below:
我尝试在 python 中计算泊松分布,如下所示:
p = math.pow(3,idx)
depart = math.exp(-3) * p
depart = depart / math.factorial(idx)
idx ranges from 0
idx 范围从 0
But I got OverflowError: long int too large to convert to float
但我得到了 OverflowError: long int too large to convert to float
I tried to convert depart to floatbut no results.
我试图将离开转换为float但没有结果。
回答by xylon97
Try using the decimal library. It claims to support arbitrary precision.from decimal import Decimal
尝试使用十进制库。它声称支持任意精度。from decimal import Decimal
Also, you don't need to use math.pow. powis in-built.
此外,您不需要使用math.pow. pow是内置的。
回答by Martijn Pieters
Factorials get large real fast:
因子变的非常快:
>>> math.factorial(170)
7257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000L
Note the L; the factorial of 170 is still convertable to a float:
注意L; 170 的阶乘仍然可以转换为浮点数:
>>> float(math.factorial(170))
7.257415615307999e+306
but the next factorial is too large:
但下一个阶乘太大:
>>> float(math.factorial(171))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float
You coulduse the decimalmodule; calculations will be slower, but the Decimal()class can handle factorials this size:
您可以使用该decimal模块;计算会更慢,但Decimal()该类可以处理这个大小的阶乘:
>>> from decimal import Decimal
>>> Decimal(math.factorial(171))
Decimal('1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000')
You'll have to use Decimal()values throughout:
您必须Decimal()在整个过程中使用值:
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)
回答by Pyrce
When idxgets large either the math.powand/or the math.factorialwill become insanely large and be unable to convert to a floating value (idx=1000triggers the error on my 64 bit machine). You'll want to not use the math.pow function as it overflows earlier than the built in **operator because it tries to keep higher precision by float converting earlier. Additionally, you can wrap each function call in a Decimalobject for higher precision.
当idx变大时,math.pow和/或math.factorial将变得非常大并且无法转换为浮点值(idx=1000在我的 64 位机器上触发错误)。您将不希望使用 math.pow 函数,因为它比内置**运算符更早溢出,因为它试图通过更早的浮点转换来保持更高的精度。此外,您可以将每个函数调用包装在一个Decimal对象中以获得更高的精度。
Another approach when dealing with very large numbers is to work in the log scale. Take the log of every value (or calculate the log version of each value) and perform all required operations before taking the exponentiation of the results. This allows for your values to temporary leave the floating domain space while still accurately computing a final answer that lies within floating domain.
处理非常大的数字时的另一种方法是在对数刻度中工作。取每个值的对数(或计算每个值的对数版本)并在对结果取幂之前执行所有必需的操作。这允许您的值暂时离开浮动域空间,同时仍然准确计算位于浮动域内的最终答案。
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 + 1))
...
math.exp(result)
This stays in the log domain until the very end so your numbers can get very, very large before you'll hit overflow problems.
这会一直保留在日志域中直到最后,因此在您遇到溢出问题之前,您的数字可能会变得非常非常大。
回答by Charles Brunet
The scipymodule could help you.
该scipy模块可以帮助您。
scipy.misc.factorialis a factorial function that can use the gamma function approximation to calculate the factorial, and returns the result using floating points.
scipy.misc.factorial是一个阶乘函数,可以使用伽马函数近似计算阶乘,并使用浮点返回结果。
import numpy
from scipy.misc import factorial
i = numpy.arange(10)
print(numpy.exp(-3) * 3**i / factorial(i))
Gives:
给出:
[ 0.04978707 0.14936121 0.22404181 0.22404181 0.16803136 0.10081881
0.05040941 0.02160403 0.00810151 0.0027005 ]
There is also a module to calculate Poisson distributions. For example:
import numpy
from scipy.stats import poisson
i = numpy.arange(10)
p = poisson(3)
print(p.pmf(i))
Gives:
给出:
[ 0.04978707 0.14936121 0.22404181 0.22404181 0.16803136 0.10081881
0.05040941 0.02160403 0.00810151 0.0027005 ]

