2 * *****************************************************************************
4 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2018-2020 Gavin D. Howard and contributors.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
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.
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.
30 * *****************************************************************************
32 * The public header for the bc library.
43 #include <sys/types.h>
45 #define BC_SEED_ULONGS (4)
46 #define BC_SEED_SIZE (sizeof(long) * BC_SEED_ULONGS)
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.
55 #define BC_LONG_BIT LONG_BIT
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
64 typedef uint64_t BclBigDig;
65 typedef uint64_t BclRandInt;
67 #elif BC_LONG_BIT >= 32
69 typedef uint32_t BclBigDig;
70 typedef uint32_t BclRandInt;
74 #error BC_LONG_BIT must be at least 32
76 #endif // BC_LONG_BIT >= 64
78 typedef enum BclError {
82 BCL_ERROR_INVALID_NUM,
83 BCL_ERROR_INVALID_CONTEXT,
86 BCL_ERROR_MATH_NEGATIVE,
87 BCL_ERROR_MATH_NON_INTEGER,
88 BCL_ERROR_MATH_OVERFLOW,
89 BCL_ERROR_MATH_DIVIDE_BY_ZERO,
91 BCL_ERROR_PARSE_INVALID_STR,
93 BCL_ERROR_FATAL_ALLOC_ERR,
94 BCL_ERROR_FATAL_UNKNOWN_ERR,
100 typedef struct BclNumber {
108 typedef struct BclCtxt* BclContext;
110 void bcl_handleSignal(void);
111 bool bcl_running(void);
113 BclError bcl_init(void);
116 bool bcl_abortOnFatalError(void);
117 void bcl_setAbortOnFatalError(bool abrt);
121 BclError bcl_pushContext(BclContext ctxt);
122 void bcl_popContext(void);
123 BclContext bcl_context(void);
125 BclContext bcl_ctxt_create(void);
126 void bcl_ctxt_free(BclContext ctxt);
127 void bcl_ctxt_freeNums(BclContext ctxt);
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);
136 BclError bcl_err(BclNumber n);
138 BclNumber bcl_num_create(void);
139 void bcl_num_free(BclNumber n);
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);
147 BclError bcl_copy(BclNumber d, BclNumber s);
148 BclNumber bcl_dup(BclNumber s);
150 BclError bcl_bigdig(BclNumber n, BclBigDig *result);
151 BclNumber bcl_bigdig2num(BclBigDig val);
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);
165 ssize_t bcl_cmp(BclNumber a, BclNumber b);
167 void bcl_zero(BclNumber n);
168 void bcl_one(BclNumber n);
170 BclNumber bcl_parse(const char *restrict val);
171 char* bcl_string(BclNumber n);
173 BclNumber bcl_irand(BclNumber a);
174 BclNumber bcl_frand(size_t places);
175 BclNumber bcl_ifrand(BclNumber a, size_t places);
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);