当分子和分母都很大时,如何避免python中的溢出

当分子和分母都很大时,如何避免python中的溢出,python,integer-overflow,Python,Integer Overflow,当我开始增加n:overflowerrror:long int太大而无法转换为float时,我得到了一个溢出错误 numTerms项变得非常大,而p^r项变得非常小。基本上,我有一个大分子除以一个大分母。有没有关于如何计算的建议?我考虑过用对数和斯特林近似公式来计算n!无济于事。任何帮助都将不胜感激 要处理大精度,可以使用十进制库: from operator import mul from fractions import Fraction import math n = 5000

当我开始增加n:overflowerrror:long int太大而无法转换为float时,我得到了一个溢出错误


numTerms
项变得非常大,而
p^r
项变得非常小。基本上,我有一个大分子除以一个大分母。有没有关于如何计算的建议?我考虑过用对数和斯特林近似公式来计算n!无济于事。任何帮助都将不胜感激

要处理大精度,可以使用
十进制
库:

from operator import mul    
from fractions import Fraction
import math

n = 5000

def nCk(n,k): 
  return int( reduce(mul, (Fraction(n-i, i+1) for i in range(k)), 1) )

p = 2.884e-5
totP = 0
sgn = 1

print "n: " + str(n)
for r in range(1, n):
    numTerms = nCk(n,r) - ((2*n-3)*(r-1))
    totP += sgn * (p ** r) * numTerms
    sgn *= -1

print "total = " + str(totP)
虽然代码很慢,但它在我的电脑上并没有停止


终于完成了,并且意识到:您打印出
str(p)
,并且您永远不会更改它。。。也许您的意思是
totP

要处理大精度,您可以使用
十进制
库:

from operator import mul    
from fractions import Fraction
import math

n = 5000

def nCk(n,k): 
  return int( reduce(mul, (Fraction(n-i, i+1) for i in range(k)), 1) )

p = 2.884e-5
totP = 0
sgn = 1

print "n: " + str(n)
for r in range(1, n):
    numTerms = nCk(n,r) - ((2*n-3)*(r-1))
    totP += sgn * (p ** r) * numTerms
    sgn *= -1

print "total = " + str(totP)
虽然代码很慢,但它在我的电脑上并没有停止


终于完成了,并且意识到:您打印出
str(p)
,并且您永远不会更改它。。。也许你的意思是
totP

如果你能容忍精度的轻微损失,你可以使用对数来完全避免除法步骤。根据定义,
a/b
等于
exp(log(a)-log(b))
。这适用于非常广泛的输入,没有过流或下流

要将其放在原始代码的上下文中,您必须:

import decimal
decimal.getcontext().prec = 100 #Or whatever precision you want...
...
p = decimal.Decimal(2.884e-5)
...
您要应用的替换为:

return int( reduce(mul, (Fraction(n-i, i+1) for i in range(k)), 1) )
我相信你的重铸函数是这样的:

[1] a*b --> exp(log(a)+log(b))
[2] c/d --> exp(log(c)-log(d))

如果您可以容忍精度的轻微损失,那么可以使用对数来完全避免除法步骤。根据定义,
a/b
等于
exp(log(a)-log(b))
。这适用于非常广泛的输入,没有过流或下流

要将其放在原始代码的上下文中,您必须:

import decimal
decimal.getcontext().prec = 100 #Or whatever precision you want...
...
p = decimal.Decimal(2.884e-5)
...
您要应用的替换为:

return int( reduce(mul, (Fraction(n-i, i+1) for i in range(k)), 1) )
我相信你的重铸函数是这样的:

[1] a*b --> exp(log(a)+log(b))
[2] c/d --> exp(log(c)-log(d))

我最终使用了scipy.misc.comb函数,并在浮点值达到“Inf”时设置了上限。

我最终使用了scipy.misc.comb函数,并在浮点值达到“Inf”时设置了上限。

是的,对不起,我在粘贴之前稍微编辑了我的代码。我对totP感兴趣。是的,对不起,我在粘贴之前稍微编辑了我的代码。我对totP很感兴趣。我曾试图做类似的事情,但不确定如何修改代码来实现这一点。我会把它放在totP计算中的第16行,还是在计算n时以某种方式嵌入nCk函数中/(右)!R请看上面我修改过的答案。我正试图做类似的事情,但不确定如何修改代码来实现这一点。我会把它放在totP计算中的第16行,还是在计算n时以某种方式嵌入nCk函数中/(右)!R请参阅上面我修改过的答案。