#ifndef __SCC_AP_H__ #define __SCC_AP_H__ /** * @brief Arbitrary Precision Library * */ #ifdef __AP_SCC__ #include #define SCC_AP_DIGIT u64 #define SCC_AP_PANIC Panic #define SCC_AP_ASSERT Assert #define SCC_AP_MALLOC scc_malloc #define SCC_AP_REALLOC scc_realloc #define SCC_AP_FREE scc_free #else #include #include #include #include #define SCC_AP_DIGIT uint64_t #define SCC_AP_PANIC(...) \ do { \ fprintf(stderr, __VA_ARGS__); \ abort(); \ } while (0) #define SCC_AP_ASSERT assert #define SCC_AP_MALLOC malloc #define SCC_AP_REALLOC realloc #define SCC_AP_FREE free #endif #ifndef SCC_AP_DIGIT #error "SCC_AP_DIGIT is not defined" #endif #define SCC_AP_DIGIT_BITS (sizeof(SCC_AP_DIGIT)) #ifndef nullptr #define nullptr ((void *)0) #endif typedef SCC_AP_DIGIT scc_ap_digit; typedef struct { int capacity; // maybe power of 2 (-1 means using digit) int len; // data length (sign with in) union { scc_ap_digit *array; scc_ap_digit digit; } data; } scc_ap_t; static inline void scc_ap_init(scc_ap_t *ap) { ap->len = 0; ap->capacity = -1; ap->len = 1; ap->data.digit = 0; } static inline void scc_ap_set_int(scc_ap_t *ap, int val) { if (val < 0) { ap->len = -1; } else { ap->len = 1; } SCC_AP_ASSERT(sizeof(scc_ap_digit) >= sizeof(int)); ap->capacity = -1; ap->data.digit = val; } void scc_ap_drop(scc_ap_t *ap); void scc_ap_with_bits(scc_ap_t *ap, int bits); void scc_ap_from_string(scc_ap_t *ap, const char *str, int len, int base); void scc_ap_set_digit(scc_ap_t *ap, scc_ap_digit digit); void scc_ap_add(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); void scc_ap_sub(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); void scc_ap_mul(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); void scc_ap_div(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); void scc_ap_mod(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); /** * @brief equal * * @param a * @param b * @return int */ int scc_ap_eql(const scc_ap_t *a, const scc_ap_t *b); typedef void (*ap_dump_fn)(const char ch, void *user_data); int scc_ap_dump(scc_ap_t *ap, ap_dump_fn dump_fn, void *user_data); #endif /* __SCC_AP_H__ */