diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-12-24 12:45:29 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-12-24 12:52:48 -0500 |
| commit | 649977aae7e5922f992cd69eb84da0a2db368580 (patch) | |
| tree | e61d35b74d2551901cc8f3f034aca7da1f375a8c /src/stdlib/bigint.c | |
| parent | 88ccdab43c0a3ee53177e21a28724e496406a376 (diff) | |
Split out new()/gc logic from stdlib/util.h
Diffstat (limited to 'src/stdlib/bigint.c')
| -rw-r--r-- | src/stdlib/bigint.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/stdlib/bigint.c b/src/stdlib/bigint.c index 2d145bd5..84da1468 100644 --- a/src/stdlib/bigint.c +++ b/src/stdlib/bigint.c @@ -18,6 +18,35 @@ #include "text.h" #include "types.h" +#define Int$from_mpz(mpz) \ + (mpz_cmpabs_ui(mpz, BIGGEST_SMALL_INT) <= 0 \ + ? ((Int_t){.small = (mpz_get_si(mpz) << 2L) | 1L}) \ + : ((Int_t){.big = memcpy(GC_MALLOC(sizeof(__mpz_struct)), mpz, sizeof(__mpz_struct))})) + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif +public +PUREFUNC Int_t Int$from_num64(double n, bool truncate) { + mpz_t result; + mpz_init_set_d(result, n); + if (!truncate && unlikely(mpz_get_d(result) != n)) fail("Could not convert to an integer without truncation: ", n); + return Int$from_mpz(result); +} + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +public +PUREFUNC Int_t Int$from_int64(int64_t i) { + if likely (i >= SMALLEST_SMALL_INT && i <= BIGGEST_SMALL_INT) return (Int_t){.small = (i << 2L) | 1L}; + mpz_t result; + mpz_init_set_si(result, i); + return Int$from_mpz(result); +} + public int Int$print(FILE *f, Int_t i) { if (likely(i.small & 1L)) { |
