1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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);
}
|