我有一些在计算中使用大整数的代码。因为我也使用numpy,似乎有些变量被设置为类型'numpy.int64',这意味着它们过流。我怎么能绕过这个?
如果您运行下面的代码,您将看到“调试信息”下的行。例如
19 1 72.7204246831 524288
19 2 2437717.7229 274877906944
19 3 149857055799.0 144115188075855872
19 4 1.73379003246e+16 0
其中前两列是n和w,最后一列是2 **(n * w)。显然0是溢出错误。
我怎样才能解决这个问题?
#!/usr/bin/python
from __future__ import division
from scipy.misc import comb
from scipy.misc import factorial
import math
import numpy as np
N = 20
X = np.arange(2,N)
def k_loop_n(w,n):
K = np.arange(0, w+1)
return (comb(w,K)*(comb(w,K)/2**w)**n).sum()
def w_loop(n):
print "w loop"
v = [comb(n,w)*k_loop_n(w,n) for w in range(1,n+1)]
print v
return sum(v)
#This is meant to be an upper bound for sum (w choose i)^(n+1), i = 0..w
def sum_upper(i,n):
return (i+1)*((2**i)*math.sqrt(2/(i*np.pi))*(1-1/(4*i)))**(n+1)
def w_loop_upv2(n):
print "w loop upper bound"
print "debugging info"
print type(n)
for w in range(1,n+1):
print n, w, sum_upper(w,n), 2**(w*n)
v = [comb(n,w)*sum_upper(w,n)/2**(w*n) for w in range(1,n+1)]
return sum(v)
def upper_k_loop(w,n):
K = np.arange(0, w+1)
return (upperbin(w,K)*(upperbin(w,K)/2**w)**(3*float(n)/np.log(n))).sum()
def upper_w_loop(n):
v = [upperbin(n,w)*k_loop(w,n) for w in range(1,n+1)]
return sum(v)
print X
Y = [w_loop(n) for n in X]
Yupper = [w_loop_upv2(n) for n in X]
print Y
print Yupper
答案 0 :(得分:3)
如果您打算使用非常大的数字,您将希望能够控制精度。看一下python库mpmath:
Mpmath是一个用于多精度浮点运算的纯Python库。它提供了一套广泛的超越函数,无限指数大小,复数,区间算术,数值积分和区分,根寻找,线性代数等等。几乎任何计算都可以在10位或1000位精度下执行,并且在许多情况下,mpmath实现了渐近快速算法,可以很好地扩展到极高精度的工作。默认情况下,Mpmath内部使用Python的内置长整数,但如果安装了gmpy或者从Sage中导入mpmath,则自动切换到GMP / MPIR以实现更快的高精度算术。
编辑:因为我可能在之前的回答中提供了上述代码:
https://stackoverflow.com/a/20576452/249341
我想重申你应该在这里使用 logrithmic 表示,除非你需要一些组合计算的确切数字。在这种情况下使用log(x)
代替x
将解决代表问题,而无需转到mpmath。
答案 1 :(得分:2)
如果超过64位整数范围,请使用浮点数。否则,如果您需要整数精度但希望值超出64位范围,则可以使用python Decimal对象。有关在numpy中使用Decimal的详细信息,请参阅this answer。