为什么"N选择k"方法scipy.misc.comb(n,k)在Python2.x和Python3.x之间存在很大差异?

Str*_*mer 0 python scipy

在项目Euler解决问题(剧透)中,这对我来说是一个问题:

15

Python2.7.10/0.13.0b1: scipy.misc.comb(40,20) -> array(137846528819.9994)

Python3.5.0/scipy 0.16.0: scipy.misc.comb(40,20) -> 137846528820.00006

令人沮丧的是,我了解到我必须round()在结果上调用函数,而不是直接转换为int()使用math.floor()/ math.ceil()用于Python 2/3的一致性.

导致两个Python/SciPy版本之间出现这种差异的原因是什么?

有没有理由SciPy开发人员不只是首先调用round()返回的结果scipy.misc.comb()

hpa*_*ulj 5

如果使用exact=True参数,则可以获得相同的整数(长整数)值.

exact : bool, optional
    If `exact` is False, then floating point precision is used, otherwise
    exact long integer is computed.
Run Code Online (Sandbox Code Playgroud)

我没有安装足够的版本,但我怀疑浮点差异与版本13和14之间的代码更改有关.13返回array()结果,14(及更高版本)返回浮点数(numpy.float64) .

我建议查看Python代码本身,看看有什么不同.在exact他们看起来相同的情况下,但浮动的情况是完全不同的.

第13节:

    from scipy import special
    k,N = asarray(k), asarray(N)
    lgam = special.gammaln
    cond = (k <= N) & (N >= 0) & (k >= 0)
    sv = special.errprint(0)
    vals = exp(lgam(N+1) - lgam(N-k+1) - lgam(k+1))
    sv = special.errprint(sv)
    return where(cond, vals, 0.0)
Run Code Online (Sandbox Code Playgroud)

第14节

    k,N = asarray(k), asarray(N)
    cond = (k <= N) & (N >= 0) & (k >= 0)
    vals = binom(N, k)
    if isinstance(vals, np.ndarray):
        vals[~cond] = 0
    elif not cond:
        vals = np.float64(0)
    return vals
Run Code Online (Sandbox Code Playgroud)

exact代码是迭代的,并且可以是较慢的(当N,k为在100秒):

    val = 1
    for j in xrange(min(k, N-k)):
        val = (val*(N-j))//(j+1)
Run Code Online (Sandbox Code Playgroud)