You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sympy.binomial与scipy.special.comb输出差异问题:为何调用comb的代码返回错误结果?

sympy.binomial与scipy.special.comb输出差异问题:为何调用comb的代码返回错误结果?

嘿,这个问题我碰到过类似的,核心原因其实是浮点数精度丢失在搞鬼!

咱们先拆解一下问题:

  • 你用scipy.special.comb得到的结果离谱到上千万,而sympy.binomial能给出正确的~49.94,本质是两者的计算方式完全不同:
    1. scipy.special.comb默认返回浮点数(哪怕你没显式指定exact=False,这是它的默认行为)。当计算comb(n-j, m)/comb(n, m)时,对于n=100这种较大的数值,当j比较小时,comb(n-j, m)和comb(n,m)的数值非常接近,它们的比值在浮点数里会被舍入,导致1 - (comb(n-j, m)/comb(n,m))变成一个极小的数——甚至可能因为精度问题被近似为0,这样coeff / denominator就会变得极大,累加后自然得到那个离谱的大数。
    2. 而sympy.binomial是精确的符号运算,它会全程保持分数形式计算,完全不会有浮点数的精度损失,所以能得到正确的结果。

那怎么解决这个问题呢?给你两个方案:

方案一:让scipy的comb做精确计算

修改comb的调用参数,加上exact=True,让它返回精确的整数,再用分数运算避免精度丢失:

from scipy.special import comb
from fractions import Fraction

def coup(n=100, m=10):
    expectation = 0.0
    for j in range(1, n + 1):
        coeff = ((-1)**(j-1)) * comb(n, j, exact=True)
        # 用Fraction保持精确分数运算
        numerator = comb(n - j, m, exact=True)
        denominator_frac = 1 - Fraction(numerator, comb(n, m, exact=True))
        expectation += coeff / denominator_frac
    
    print(expectation)

这样计算出来的结果就会和sympy版本完全一致,因为全程都是精确计算,没有浮点数误差。

方案二:继续使用sympy的binomial

如果你的场景对计算精度要求高,sympy的符号运算天生就适合这种场景,不需要额外调整,直接用它的binomial就好:

from sympy import binomial

def coup(n=100, m=10):
    expectation = 0
    for j in range(1, n + 1):
        coeff = ((-1)**(j-1)) * binomial(n, j)
        denominator = 1 - (binomial(n - j, m) / binomial(n, m))
        expectation += coeff / denominator
    
    print(expectation)

它会自动处理精确的分数运算,不会出现精度丢失的问题。

备注:内容来源于stack exchange,提问作者bettersayhello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:59:30