]>
Commit | Line | Data |
---|---|---|
b7cd3db6 AK |
1 | #ifndef INT128_H |
2 | #define INT128_H | |
3 | ||
4 | typedef struct Int128 Int128; | |
5 | ||
6 | struct Int128 { | |
7 | uint64_t lo; | |
8 | int64_t hi; | |
9 | }; | |
10 | ||
11 | static inline Int128 int128_make64(uint64_t a) | |
12 | { | |
13 | return (Int128) { a, 0 }; | |
14 | } | |
15 | ||
16 | static inline uint64_t int128_get64(Int128 a) | |
17 | { | |
18 | assert(!a.hi); | |
19 | return a.lo; | |
20 | } | |
21 | ||
22 | static inline Int128 int128_zero(void) | |
23 | { | |
24 | return int128_make64(0); | |
25 | } | |
26 | ||
27 | static inline Int128 int128_one(void) | |
28 | { | |
29 | return int128_make64(1); | |
30 | } | |
31 | ||
32 | static inline Int128 int128_2_64(void) | |
33 | { | |
34 | return (Int128) { 0, 1 }; | |
35 | } | |
36 | ||
37 | static inline Int128 int128_add(Int128 a, Int128 b) | |
38 | { | |
39 | Int128 r = { a.lo + b.lo, a.hi + b.hi }; | |
40 | r.hi += (r.lo < a.lo) || (r.lo < b.lo); | |
41 | return r; | |
42 | } | |
43 | ||
44 | static inline Int128 int128_neg(Int128 a) | |
45 | { | |
46 | a.lo = ~a.lo; | |
47 | a.hi = ~a.hi; | |
48 | return int128_add(a, int128_one()); | |
49 | } | |
50 | ||
51 | static inline Int128 int128_sub(Int128 a, Int128 b) | |
52 | { | |
53 | return int128_add(a, int128_neg(b)); | |
54 | } | |
55 | ||
56 | static inline bool int128_nonneg(Int128 a) | |
57 | { | |
58 | return a.hi >= 0; | |
59 | } | |
60 | ||
61 | static inline bool int128_eq(Int128 a, Int128 b) | |
62 | { | |
63 | return a.lo == b.lo && a.hi == b.hi; | |
64 | } | |
65 | ||
66 | static inline bool int128_ne(Int128 a, Int128 b) | |
67 | { | |
68 | return !int128_eq(a, b); | |
69 | } | |
70 | ||
71 | static inline bool int128_ge(Int128 a, Int128 b) | |
72 | { | |
73 | return int128_nonneg(int128_sub(a, b)); | |
74 | } | |
75 | ||
76 | static inline bool int128_lt(Int128 a, Int128 b) | |
77 | { | |
78 | return !int128_ge(a, b); | |
79 | } | |
80 | ||
81 | static inline bool int128_le(Int128 a, Int128 b) | |
82 | { | |
83 | return int128_ge(b, a); | |
84 | } | |
85 | ||
86 | static inline bool int128_gt(Int128 a, Int128 b) | |
87 | { | |
88 | return !int128_le(a, b); | |
89 | } | |
90 | ||
91 | static inline bool int128_nz(Int128 a) | |
92 | { | |
93 | return a.lo || a.hi; | |
94 | } | |
95 | ||
96 | static inline Int128 int128_min(Int128 a, Int128 b) | |
97 | { | |
98 | return int128_le(a, b) ? a : b; | |
99 | } | |
100 | ||
101 | static inline Int128 int128_max(Int128 a, Int128 b) | |
102 | { | |
103 | return int128_ge(a, b) ? a : b; | |
104 | } | |
105 | ||
106 | static inline void int128_addto(Int128 *a, Int128 b) | |
107 | { | |
108 | *a = int128_add(*a, b); | |
109 | } | |
110 | ||
111 | static inline void int128_subfrom(Int128 *a, Int128 b) | |
112 | { | |
113 | *a = int128_sub(*a, b); | |
114 | } | |
115 | ||
116 | #endif |