maxint.h (3731B)
1#pragma once 2 3#include <stdint.h> 4#include <stdbool.h> 5#include <stdlib.h> 6 7#define MI_NEG 1 8#define MI_POS 0 9 10#define MI_BIT(a,n) ((mi_ul) ((a) >> (n)) & 1) 11#define MI_BITA(a,m,n) ((mi_ul) ((a)[(n) / (m)] >> ((n) % (m))) & 1) 12 13#define MI_UL_BYTES (sizeof(mi_ul)) 14#define MI_UL_BITS (8 * sizeof(mi_ul)) 15 16#define MI_ULS_BYTES (sizeof(mi_uls)) 17#define MI_ULS_BITS (8 * sizeof(mi_uls)) 18 19#define MI_ABS(x) ((mi_ul) ((x) > 0 ? (x) : -(x))) 20#define MI_SIGN(x) ((x) >= 0 ? MI_POS : MI_NEG) 21#define MI_TO_SIGN(x) ((x)->sign == MI_POS ? 1 : -1) 22 23#define MI_INIT ((struct maxint) { \ 24 .data = NULL, \ 25 .size = 0, \ 26 .cap = 0, \ 27 .sign = MI_POS, \ 28}) 29 30/* unsigned underlying type */ 31typedef uint64_t mi_ul; 32typedef int64_t mi_uls; 33 34enum { 35 MI_OK, 36 MI_ERR_OOM, 37 MI_ERR_INVAL, 38}; 39 40struct maxint { 41 mi_ul *data; 42 size_t size, cap; 43 int sign; 44}; 45 46/* void mi_init(struct maxint *m); */ 47void mi_deinit(struct maxint *m); 48 49/* struct maxint *mi_imm(struct maxint *storage, mi_ul tmp, int sign); */ 50 51int mi_set(struct maxint *m1, const struct maxint *m2); 52int mi_setv(struct maxint *m, mi_ul v, int sign); 53int mi_setstr(struct maxint *m, const char *str, 54 const char **end, const char *alph); 55 56int mi_resize(struct maxint *m, size_t size); 57 58static inline mi_ul mi_cast_ul(const struct maxint *m); 59static inline mi_uls mi_cast_uls(const struct maxint *m); 60 61bool mi_zero(const struct maxint *m); 62 63size_t mi_lastset(const struct maxint *m); 64 65ssize_t mi_str(const struct maxint *m, char *buf, size_t buflen, 66 mi_ul base, const char *alph, size_t zfill); 67ssize_t mi_hex(const struct maxint *m, char *buf, size_t buflen, 68 bool capital, size_t zfill); 69ssize_t mi_dec(const struct maxint *m, char *buf, size_t buflen, size_t zfill); 70ssize_t mi_bin(const struct maxint *m, char *buf, size_t buflen, size_t zfill); 71 72/* mi_add: o1 = i1 + i2 73 * allowed: o1 == i1 */ 74int mi_add(struct maxint *o1, const struct maxint *i1, const struct maxint *i2); 75 76/* mi_sub: o1 = i1 - i2 77 * allowed: o1 == i1 */ 78int mi_sub(struct maxint *o1, const struct maxint *i1, const struct maxint *i2); 79 80/* mi_shl: o1 = i1 << shift 81 * allowed: o1 == i1 */ 82int mi_shl(struct maxint *o1, const struct maxint *i1, size_t shift); 83 84/* mi_shr: o1 = i1 >> shift 85 * allowed: o1 == i1 */ 86int mi_shr(struct maxint *o1, const struct maxint *i1, size_t shift); 87 88/* mi_mul: o1 = i1 * i2 89 * allowed: o1 == i1 */ 90int mi_mul(struct maxint *o1, const struct maxint *i1, const struct maxint *i2); 91 92/* mi_div: o1 = i1 / i2, o2 = i1 % i2 93 * allowed: o1 == i1 */ 94int mi_div(struct maxint *o1, struct maxint *o2, 95 const struct maxint *i1, const struct maxint *i2); 96 97/* mi_swap: o1 <=> o2 */ 98void mi_swap(struct maxint *o1, struct maxint *o2); 99 100/* mi_gcm: o1 = gcm(i1, i2) 101 * allowed: o1 == i1 */ 102int mi_gcm(struct maxint *o1, const struct maxint *i1, const struct maxint *i2); 103 104/* mi_lcm: o1 = lcm(i1, i2) 105 * allowed: o1 == i1 */ 106int mi_lcm(struct maxint *o1, const struct maxint *i1, const struct maxint *i2); 107 108/* mi_cmp: (i1 < i2) => -1 | (i1 == i2) => 0 | (i1 < i2) => 1 */ 109int mi_cmp(const struct maxint *i1, const struct maxint *i2); 110 111static inline void 112mi_init(struct maxint *m) 113{ 114 m->data = NULL; 115 m->size = 0; 116 m->cap = 0; 117 m->sign = MI_POS; 118} 119 120static inline struct maxint * 121mi_imm(struct maxint *mi_tmp, mi_ul *ul_tmp, mi_ul imm, int sign) 122{ 123 mi_tmp->sign = sign; 124 if (mi_tmp->data) { 125 mi_tmp->data[0] = imm; 126 } else { 127 *ul_tmp = imm; 128 mi_tmp->data = ul_tmp; 129 } 130 mi_tmp->size = 1; 131 return mi_tmp; 132} 133 134static inline mi_ul 135mi_cast_ul(const struct maxint *m) 136{ 137 return m->data[0]; 138} 139 140static inline mi_uls 141mi_cast_uls(const struct maxint *m) 142{ 143 mi_uls val; 144 mi_ul mask; 145 146 mask = (((mi_ul) 1) << (MI_ULS_BITS - 1)) - 1; 147 val = (mi_uls) (m->data[0] & mask); 148 149 return val * MI_TO_SIGN(m);; 150} 151