This language bar is your friend. Select your favorite languages!
Select your favorite languages :
- Or search :
long long binom(long long n, long long k){
long long outp = 1;
for(long long i = n - k + 1; i <= n; ++i) outp *= i;
for(long long i = 2; i <= k; ++i) outp /= i;
return outp;
}
c does not have a BigInt type, as a substitute long long is used.
To increase the range as much as possible, the formula is slightly different than the one presented in the idiom, but it gives the same results.
To increase the range as much as possible, the formula is slightly different than the one presented in the idiom, but it gives the same results.
integer, parameter :: i8 = selected_int_kind(18)
integer, parameter :: dp = selected_real_kind(15)
n = 100
k = 5
print *,nint(exp(log_gamma(n+1.0_dp)-log_gamma(n-k+1.0_dp)-log_gamma(k+1.0_dp)),kind=i8)
Sorry, Fortran does not do huge integers. The next best thing is probably to calculate the binomial coefficient using the Gamma function, or rather its logarithm, to get an approximation which it is then possible to round. Works for a rather large range.
sub binom {
my ($n, $k) = @_;
if ($k > $n - $k) { $k = $n - $k }
my $r = 1;
for ( my $i = $n/$n ; $i <= $k;) {
$r *= $n-- / $i++
}
return $r
}
This algorithm is faster and uses less memory than naïve use of factorials.
Because it does not generate huge intermediate values, it can calculate a reasonable approximation to ¹⁰⁰⁰C₅₀₀ using IEEE double-precision FP without needing BigNum support; however it will calculate the exact answer if either parameter is a BigNum.
As a further optimisation, this algorithm takes advantage of the identity ⁿCₖ≡ⁿC₍ₙ₋ₖ₎.
$i inherits the type of $n.
Because it does not generate huge intermediate values, it can calculate a reasonable approximation to ¹⁰⁰⁰C₅₀₀ using IEEE double-precision FP without needing BigNum support; however it will calculate the exact answer if either parameter is a BigNum.
As a further optimisation, this algorithm takes advantage of the identity ⁿCₖ≡ⁿC₍ₙ₋ₖ₎.
$i inherits the type of $n.
fn binom(n: u64, k: u64) -> BigInt {
let mut res = BigInt::one();
for i in 0..k {
res = (res * (n - i).to_bigint().unwrap()) /
(i + 1).to_bigint().unwrap();
}
res
}