diff --git a/applets/qrpn/qrpn.c b/applets/qrpn/qrpn.c index 55bf52bd..fa13ce0c 100644 --- a/applets/qrpn/qrpn.c +++ b/applets/qrpn/qrpn.c @@ -13,6 +13,7 @@ #include #include #include +#include /* begin simple math functions we want to expose via the interpreter */ @@ -74,12 +75,16 @@ static unsigned long long gcd(unsigned long long a, unsigned long long b) { return a; } -static unsigned long long nchoosek(const unsigned long long n, const unsigned long long k) { - if (1 == k) return n; +static unsigned long long nchoosek(unsigned long long n, const unsigned long long k) { if (k > n - k) return nchoosek(n, n - k); - unsigned long long n_choose_k = n * (n - 1) / 2; - for (size_t kr = 3; kr <= k; kr++) - n_choose_k *= (n + 1 - kr) / kr; + + unsigned long long n_choose_k = 1; + for (unsigned long long i = 1; i <= k; i++, n--) { + /* give up */ + if (n_choose_k / i > ULLONG_MAX / n) return 0; + + n_choose_k = n_choose_k / i * n + n_choose_k % i * n / i; + } return n_choose_k; }