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 /libquanta_bigint_divmod_small__.c | |
| 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 'libquanta_bigint_divmod_small__.c')
| -rw-r--r-- | libquanta_bigint_divmod_small__.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/libquanta_bigint_divmod_small__.c b/libquanta_bigint_divmod_small__.c new file mode 100644 index 0000000..a2c345f --- /dev/null +++ b/libquanta_bigint_divmod_small__.c @@ -0,0 +1,34 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +uintmax_t +libquanta_bigint_divmod_small__(struct bigint *big, uintmax_t small) +{ + uintmax_t q = 0, hi, lo; + int e = 8 * (int)sizeof(small); + +#if 0 /* this would overflow (undefined behaviour) and not fit in the result */ + q = big->high / small; + q <<= 8 * (int)sizeof(small); +#endif + big->high %= small; + + while (big->high && --e) { + hi = small >> (8 * (int)sizeof(small) - e); + lo = small << e; + + if (hi > big->high) + continue; + if (hi == big->high && lo > big->low) + continue; + + q |= (uintmax_t)1 << e; + bigint_sub_small(big, lo); + big->high -= hi; + } + + q += big->low / small; + big->low %= small; + return q; +} |
