1 /* 2 * ***************************************************************************** 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2018-2021 Gavin D. Howard and contributors. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * * Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ***************************************************************************** 31 * 32 * The public header for the bc library. 33 * 34 */ 35 36 #ifndef BC_BCL_H 37 #define BC_BCL_H 38 39 #include <stdbool.h> 40 #include <stdlib.h> 41 #include <limits.h> 42 #include <stdint.h> 43 #include <sys/types.h> 44 45 #define BC_SEED_ULONGS (4) 46 #define BC_SEED_SIZE (sizeof(long) * BC_SEED_ULONGS) 47 48 // For some reason, LONG_BIT is not defined in some versions of gcc. 49 // I define it here to the minimum accepted value in the POSIX standard. 50 #ifndef LONG_BIT 51 #define LONG_BIT (32) 52 #endif // LONG_BIT 53 54 #ifndef BC_LONG_BIT 55 #define BC_LONG_BIT LONG_BIT 56 #endif // BC_LONG_BIT 57 58 #if BC_LONG_BIT > LONG_BIT 59 #error BC_LONG_BIT cannot be greater than LONG_BIT 60 #endif // BC_LONG_BIT > LONG_BIT 61 62 #if BC_LONG_BIT >= 64 63 64 typedef uint64_t BclBigDig; 65 typedef uint64_t BclRandInt; 66 67 #elif BC_LONG_BIT >= 32 68 69 typedef uint32_t BclBigDig; 70 typedef uint32_t BclRandInt; 71 72 #else 73 74 #error BC_LONG_BIT must be at least 32 75 76 #endif // BC_LONG_BIT >= 64 77 78 typedef enum BclError { 79 80 BCL_ERROR_NONE, 81 82 BCL_ERROR_INVALID_NUM, 83 BCL_ERROR_INVALID_CONTEXT, 84 BCL_ERROR_SIGNAL, 85 86 BCL_ERROR_MATH_NEGATIVE, 87 BCL_ERROR_MATH_NON_INTEGER, 88 BCL_ERROR_MATH_OVERFLOW, 89 BCL_ERROR_MATH_DIVIDE_BY_ZERO, 90 91 BCL_ERROR_PARSE_INVALID_STR, 92 93 BCL_ERROR_FATAL_ALLOC_ERR, 94 BCL_ERROR_FATAL_UNKNOWN_ERR, 95 96 BCL_ERROR_NELEMS, 97 98 } BclError; 99 100 typedef struct BclNumber { 101 102 size_t i; 103 104 } BclNumber; 105 106 struct BclCtxt; 107 108 typedef struct BclCtxt* BclContext; 109 110 void bcl_handleSignal(void); 111 bool bcl_running(void); 112 113 BclError bcl_init(void); 114 void bcl_free(void); 115 116 bool bcl_abortOnFatalError(void); 117 void bcl_setAbortOnFatalError(bool abrt); 118 119 void bcl_gc(void); 120 121 BclError bcl_pushContext(BclContext ctxt); 122 void bcl_popContext(void); 123 BclContext bcl_context(void); 124 125 BclContext bcl_ctxt_create(void); 126 void bcl_ctxt_free(BclContext ctxt); 127 void bcl_ctxt_freeNums(BclContext ctxt); 128 129 size_t bcl_ctxt_scale(BclContext ctxt); 130 void bcl_ctxt_setScale(BclContext ctxt, size_t scale); 131 size_t bcl_ctxt_ibase(BclContext ctxt); 132 void bcl_ctxt_setIbase(BclContext ctxt, size_t ibase); 133 size_t bcl_ctxt_obase(BclContext ctxt); 134 void bcl_ctxt_setObase(BclContext ctxt, size_t obase); 135 136 BclError bcl_err(BclNumber n); 137 138 BclNumber bcl_num_create(void); 139 void bcl_num_free(BclNumber n); 140 141 bool bcl_num_neg(BclNumber n); 142 void bcl_num_setNeg(BclNumber n, bool neg); 143 size_t bcl_num_scale(BclNumber n); 144 BclError bcl_num_setScale(BclNumber n, size_t scale); 145 size_t bcl_num_len(BclNumber n); 146 147 BclError bcl_copy(BclNumber d, BclNumber s); 148 BclNumber bcl_dup(BclNumber s); 149 150 BclError bcl_bigdig(BclNumber n, BclBigDig *result); 151 BclNumber bcl_bigdig2num(BclBigDig val); 152 153 BclNumber bcl_add(BclNumber a, BclNumber b); 154 BclNumber bcl_sub(BclNumber a, BclNumber b); 155 BclNumber bcl_mul(BclNumber a, BclNumber b); 156 BclNumber bcl_div(BclNumber a, BclNumber b); 157 BclNumber bcl_mod(BclNumber a, BclNumber b); 158 BclNumber bcl_pow(BclNumber a, BclNumber b); 159 BclNumber bcl_lshift(BclNumber a, BclNumber b); 160 BclNumber bcl_rshift(BclNumber a, BclNumber b); 161 BclNumber bcl_sqrt(BclNumber a); 162 BclError bcl_divmod(BclNumber a, BclNumber b, BclNumber *c, BclNumber *d); 163 BclNumber bcl_modexp(BclNumber a, BclNumber b, BclNumber c); 164 165 ssize_t bcl_cmp(BclNumber a, BclNumber b); 166 167 void bcl_zero(BclNumber n); 168 void bcl_one(BclNumber n); 169 170 BclNumber bcl_parse(const char *restrict val); 171 char* bcl_string(BclNumber n); 172 173 BclNumber bcl_irand(BclNumber a); 174 BclNumber bcl_frand(size_t places); 175 BclNumber bcl_ifrand(BclNumber a, size_t places); 176 177 BclError bcl_rand_seedWithNum(BclNumber n); 178 BclError bcl_rand_seed(unsigned char seed[BC_SEED_SIZE]); 179 void bcl_rand_reseed(void); 180 BclNumber bcl_rand_seed2num(void); 181 BclRandInt bcl_rand_int(void); 182 BclRandInt bcl_rand_bounded(BclRandInt bound); 183 184 #endif // BC_BCL_H 185