diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-12-24 14:20:16 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-12-24 14:20:16 -0500 |
| commit | 9e0017e86ed28ccc2f855807f387a1e451260d85 (patch) | |
| tree | 7fe1b0b931dc82777d8b471e95147eb1edfda184 /stdlib | |
| parent | f4b105456ad5f0949800d19acdb3403de26d7678 (diff) | |
Add Int:factorial() and n:choose(k)
Diffstat (limited to 'stdlib')
| -rw-r--r-- | stdlib/integers.c | 33 | ||||
| -rw-r--r-- | stdlib/integers.h | 2 |
2 files changed, 35 insertions, 0 deletions
diff --git a/stdlib/integers.c b/stdlib/integers.c index 33e967cb..e5344370 100644 --- a/stdlib/integers.c +++ b/stdlib/integers.c @@ -382,6 +382,39 @@ public Int_t Int$prev_prime(Int_t x) return Int$from_mpz(p); } +public Int_t Int$choose(Int_t n, Int_t k) +{ + if unlikely (Int$compare_value(n, I_small(0)) < 0) + fail("Negative inputs are not supported for choose()"); + + mpz_t ret; + mpz_init(ret); + + int64_t k_i64 = Int_to_Int64(k, false); + if unlikely (k_i64 < 0) + fail("Negative inputs are not supported for choose()"); + + if likely (n.small & 1) { + mpz_bin_uiui(ret, (unsigned long)(n.small >> 2), (unsigned long)k_i64); + } else { + mpz_t n_mpz; + mpz_init_set_int(n_mpz, n); + mpz_bin_ui(ret, n_mpz, (unsigned long)k_i64); + } + return Int$from_mpz(ret); +} + +public Int_t Int$factorial(Int_t n) +{ + mpz_t ret; + mpz_init(ret); + int64_t n_i64 = Int_to_Int64(n, false); + if unlikely (n_i64 < 0) + fail("Factorials are not defined for negative numbers"); + mpz_fac_ui(ret, (unsigned long)n_i64); + return Int$from_mpz(ret); +} + static bool Int$is_none(const void *i, const TypeInfo_t*) { return ((Int_t*)i)->small == 0; diff --git a/stdlib/integers.h b/stdlib/integers.h index 2f6b5125..033a6873 100644 --- a/stdlib/integers.h +++ b/stdlib/integers.h @@ -144,6 +144,8 @@ Int_t Int$slow_negated(Int_t x); bool Int$is_prime(Int_t x, Int_t reps); Int_t Int$next_prime(Int_t x); Int_t Int$prev_prime(Int_t x); +Int_t Int$choose(Int_t n, Int_t k); +Int_t Int$factorial(Int_t n); extern const TypeInfo_t Int$info; |
