다른 대안이 있습니다. 이것은 원래 C ++로 작성되었으므로 유한 정밀도 정수 (예 : __int64)를 위해 C ++로 백 포트 할 수 있습니다. 장점은 (1) 정수 연산 만 포함하고 (2) 연속적인 곱셈과 나눗셈 쌍을 수행하여 정수 값의 팽창을 방지한다는 것입니다. Nas Banov의 Pascal 삼각형으로 결과를 테스트했는데 정답을 얻었습니다.
def choose(n,r):
"""Computes n! / (r! (n-r)!) exactly. Returns a python long int."""
assert n >= 0
assert 0 <= r <= n
c = 1L
denom = 1
for (num,denom) in zip(xrange(n,n-r,-1), xrange(1,r+1,1)):
c = (c * num) // denom
return c
근거 : 곱셈과 나눗셈의 수를 최소화하기 위해 식을 다음과 같이 다시 작성합니다.
n! n(n-1)...(n-r+1)
--------- = ----------------
r!(n-r)! r!
곱셈 오버플로를 최대한 피하기 위해 왼쪽에서 오른쪽으로 다음 STRICT 순서로 평가합니다.
n / 1 * (n-1) / 2 * (n-2) / 3 * ... * (n-r+1) / r
이 순서로 연산 된 정수 산술이 정확하다는 것을 보여줄 수 있습니다 (즉, 반올림 오류가 없음).
scipy.misc.comb
scipy.special.comb
이후 버전 대신 사용되지 않습니다0.10.0
.