diff options
| author | Mattias Andrée <m@maandree.se> | 2025-11-23 21:33:38 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2025-11-23 21:33:38 +0100 |
| commit | 226d807bb8bc0cdbc011b2e616ac02881e74c542 (patch) | |
| tree | e35bcc0f0b2bad8abfbb5da6db5580a813ca48bc /common.h | |
| download | libquanta-226d807bb8bc0cdbc011b2e616ac02881e74c542.tar.gz libquanta-226d807bb8bc0cdbc011b2e616ac02881e74c542.tar.bz2 libquanta-226d807bb8bc0cdbc011b2e616ac02881e74c542.tar.xz | |
First commit
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'common.h')
| -rw-r--r-- | common.h | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/common.h b/common.h new file mode 100644 index 0000000..b299fd1 --- /dev/null +++ b/common.h @@ -0,0 +1,91 @@ +/* See LICENSE file for copyright and license details. */ +#include "libquanta.h" +#include <errno.h> +#include <limits.h> +#include <math.h> +#include <stdlib.h> + + +#define PALETTE_BASE_SIZE offsetof(struct libquanta_palette, palette) +#define PALETTE_VALUE_TYPE uint64_t +#define PALETTE_VALUE_SIZE sizeof(PALETTE_VALUE_TYPE) +#define PALETTE_VALUE_MAX_BITS 64U + + +struct bigint { + uintmax_t high, low; +}; + + +#if defined(__GNUC__) +__attribute__((__visibility__("hidden"))) +#endif +uintmax_t libquanta_bigint_divmod_small__(struct bigint *big, uintmax_t small); +#define bigint_divmod_small libquanta_bigint_divmod_small__ + + +static inline void +bigint_add_small(struct bigint *big, uintmax_t small) +{ +#if defined(__GNUC__) + if (__builtin_add_overflow(big->low, small, &big->low)) + big->high += 1U; +#else + if (big->low > UINTMAX_MAX - small) + big->high += 1U; + big->low += small; +#endif +} + + +static inline void +bigint_sub_small(struct bigint *big, uintmax_t small) +{ +#if defined(__GNUC__) + if (__builtin_sub_overflow(big->low, small, &big->low)) + big->high -= 1U; +#else + if (big->low < small) + big->high -= 1U; + big->low -= small; +#endif +} + + +static inline void +bigint_add_big(struct bigint *res, const struct bigint *restrict other) +{ + bigint_add_small(res, other->low); + res->high += other->high; +} + + +static inline void +bigint_sub_big(struct bigint *res, const struct bigint *restrict other) +{ + bigint_sub_small(res, other->low); + res->high -= other->high; +} + + +static inline void +bigint_rsub_big(struct bigint *res, const struct bigint *restrict other) +{ + res->high = other->high - res->high; +#if defined(__GNUC__) + if (__builtin_sub_overflow(other->low, res->low, &res->low)) + res->high -= 1U; +#else + if (res->low > other->low) + res->high -= 1U; + res->low = other->low - res->low; +#endif +} + + +static inline uintmax_t +bigint_div_small(const struct bigint *big, uintmax_t small) +{ + struct bigint big_copy = *big; + return bigint_divmod_small(&big_copy, small); +} |
