xref: /freebsd/contrib/bc/include/bcl.h (revision aa339f1d)
150696a6eSStefan Eßer /*
250696a6eSStefan Eßer  * *****************************************************************************
350696a6eSStefan Eßer  *
450696a6eSStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
550696a6eSStefan Eßer  *
6d101cdd6SStefan Eßer  * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
750696a6eSStefan Eßer  *
850696a6eSStefan Eßer  * Redistribution and use in source and binary forms, with or without
950696a6eSStefan Eßer  * modification, are permitted provided that the following conditions are met:
1050696a6eSStefan Eßer  *
1150696a6eSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
1250696a6eSStefan Eßer  *   list of conditions and the following disclaimer.
1350696a6eSStefan Eßer  *
1450696a6eSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
1550696a6eSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
1650696a6eSStefan Eßer  *   and/or other materials provided with the distribution.
1750696a6eSStefan Eßer  *
1850696a6eSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1950696a6eSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2050696a6eSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2150696a6eSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2250696a6eSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2350696a6eSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2450696a6eSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2550696a6eSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2650696a6eSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2750696a6eSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2850696a6eSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
2950696a6eSStefan Eßer  *
3050696a6eSStefan Eßer  * *****************************************************************************
3150696a6eSStefan Eßer  *
3250696a6eSStefan Eßer  * The public header for the bc library.
3350696a6eSStefan Eßer  *
3450696a6eSStefan Eßer  */
3550696a6eSStefan Eßer 
3650696a6eSStefan Eßer #ifndef BC_BCL_H
3750696a6eSStefan Eßer #define BC_BCL_H
3850696a6eSStefan Eßer 
39d101cdd6SStefan Eßer #include <stdbool.h>
40d101cdd6SStefan Eßer #include <stdlib.h>
41d101cdd6SStefan Eßer #include <limits.h>
42d101cdd6SStefan Eßer #include <stdint.h>
43d101cdd6SStefan Eßer 
44103d7cdfSStefan Eßer #ifndef NDEBUG
45103d7cdfSStefan Eßer #define BC_DEBUG (1)
46103d7cdfSStefan Eßer #else // NDEBUG
47103d7cdfSStefan Eßer #define BC_DEBUG (0)
48103d7cdfSStefan Eßer #endif // NDEBUG
49103d7cdfSStefan Eßer 
507e5c51e5SStefan Eßer #ifdef _WIN32
517e5c51e5SStefan Eßer #include <Windows.h>
527e5c51e5SStefan Eßer #include <BaseTsd.h>
537e5c51e5SStefan Eßer #include <stdio.h>
547e5c51e5SStefan Eßer #include <io.h>
557e5c51e5SStefan Eßer #endif // _WIN32
567e5c51e5SStefan Eßer 
577e5c51e5SStefan Eßer #ifdef _WIN32
587e5c51e5SStefan Eßer #define ssize_t SSIZE_T
597e5c51e5SStefan Eßer #endif // _WIN32
607e5c51e5SStefan Eßer 
6144d4804dSStefan Eßer #define BCL_SEED_ULONGS (4)
6244d4804dSStefan Eßer #define BCL_SEED_SIZE (sizeof(long) * BCL_SEED_ULONGS)
6344d4804dSStefan Eßer 
6444d4804dSStefan Eßer // For some reason, LONG_BIT is not defined in some versions of gcc.
6544d4804dSStefan Eßer // I define it here to the minimum accepted value in the POSIX standard.
6644d4804dSStefan Eßer #ifndef LONG_BIT
6744d4804dSStefan Eßer #define LONG_BIT (32)
6844d4804dSStefan Eßer #endif // LONG_BIT
6944d4804dSStefan Eßer 
7044d4804dSStefan Eßer #ifndef BC_LONG_BIT
7144d4804dSStefan Eßer #define BC_LONG_BIT LONG_BIT
7244d4804dSStefan Eßer #endif // BC_LONG_BIT
7344d4804dSStefan Eßer 
7444d4804dSStefan Eßer #if BC_LONG_BIT > LONG_BIT
7544d4804dSStefan Eßer #error BC_LONG_BIT cannot be greater than LONG_BIT
7644d4804dSStefan Eßer #endif // BC_LONG_BIT > LONG_BIT
7744d4804dSStefan Eßer 
7844d4804dSStefan Eßer // For more information about the items here, see the either the
7944d4804dSStefan Eßer // manuals/bcl.3.md or manuals/bcl.3 manuals.
8044d4804dSStefan Eßer 
8144d4804dSStefan Eßer // BclBigDig is a fixed-size integer type that bcl can convert numbers to.
8244d4804dSStefan Eßer //
8344d4804dSStefan Eßer // BclRandInt is the type of fixed-size integer natively returned by the
8444d4804dSStefan Eßer // pseudo-random number generator.
8544d4804dSStefan Eßer #if BC_LONG_BIT >= 64
8644d4804dSStefan Eßer 
8744d4804dSStefan Eßer typedef uint64_t BclBigDig;
8844d4804dSStefan Eßer typedef uint64_t BclRandInt;
8944d4804dSStefan Eßer 
9044d4804dSStefan Eßer #elif BC_LONG_BIT >= 32
9144d4804dSStefan Eßer 
9244d4804dSStefan Eßer typedef uint32_t BclBigDig;
9344d4804dSStefan Eßer typedef uint32_t BclRandInt;
9444d4804dSStefan Eßer 
9544d4804dSStefan Eßer #else
9644d4804dSStefan Eßer 
9744d4804dSStefan Eßer #error BC_LONG_BIT must be at least 32
9844d4804dSStefan Eßer 
9944d4804dSStefan Eßer #endif // BC_LONG_BIT >= 64
10044d4804dSStefan Eßer 
10144d4804dSStefan Eßer #ifndef BC_ENABLE_LIBRARY
10244d4804dSStefan Eßer #define BC_ENABLE_LIBRARY (1)
10344d4804dSStefan Eßer #endif // BC_ENABLE_LIBRARY
10444d4804dSStefan Eßer 
1057e5c51e5SStefan Eßer #if BC_ENABLE_LIBRARY
10650696a6eSStefan Eßer 
10778bc019dSStefan Eßer typedef enum BclError
10878bc019dSStefan Eßer {
10950696a6eSStefan Eßer 	BCL_ERROR_NONE,
11050696a6eSStefan Eßer 
11150696a6eSStefan Eßer 	BCL_ERROR_INVALID_NUM,
11250696a6eSStefan Eßer 	BCL_ERROR_INVALID_CONTEXT,
11350696a6eSStefan Eßer 	BCL_ERROR_SIGNAL,
11450696a6eSStefan Eßer 
11550696a6eSStefan Eßer 	BCL_ERROR_MATH_NEGATIVE,
11650696a6eSStefan Eßer 	BCL_ERROR_MATH_NON_INTEGER,
11750696a6eSStefan Eßer 	BCL_ERROR_MATH_OVERFLOW,
11850696a6eSStefan Eßer 	BCL_ERROR_MATH_DIVIDE_BY_ZERO,
11950696a6eSStefan Eßer 
12050696a6eSStefan Eßer 	BCL_ERROR_PARSE_INVALID_STR,
12150696a6eSStefan Eßer 
12250696a6eSStefan Eßer 	BCL_ERROR_FATAL_ALLOC_ERR,
12350696a6eSStefan Eßer 	BCL_ERROR_FATAL_UNKNOWN_ERR,
12450696a6eSStefan Eßer 
12550696a6eSStefan Eßer 	BCL_ERROR_NELEMS,
12650696a6eSStefan Eßer 
12750696a6eSStefan Eßer } BclError;
12850696a6eSStefan Eßer 
12978bc019dSStefan Eßer typedef struct BclNumber
13078bc019dSStefan Eßer {
13150696a6eSStefan Eßer 	size_t i;
13250696a6eSStefan Eßer 
13350696a6eSStefan Eßer } BclNumber;
13450696a6eSStefan Eßer 
13550696a6eSStefan Eßer struct BclCtxt;
13650696a6eSStefan Eßer 
13750696a6eSStefan Eßer typedef struct BclCtxt* BclContext;
13850696a6eSStefan Eßer 
139d101cdd6SStefan Eßer BclError
140d101cdd6SStefan Eßer bcl_start(void);
14150696a6eSStefan Eßer 
142d101cdd6SStefan Eßer void
143d101cdd6SStefan Eßer bcl_end(void);
14450696a6eSStefan Eßer 
14578bc019dSStefan Eßer BclError
14678bc019dSStefan Eßer bcl_init(void);
14750696a6eSStefan Eßer 
14878bc019dSStefan Eßer void
14978bc019dSStefan Eßer bcl_free(void);
15050696a6eSStefan Eßer 
15178bc019dSStefan Eßer bool
15278bc019dSStefan Eßer bcl_abortOnFatalError(void);
15350696a6eSStefan Eßer 
15478bc019dSStefan Eßer void
15578bc019dSStefan Eßer bcl_setAbortOnFatalError(bool abrt);
15650696a6eSStefan Eßer 
15778bc019dSStefan Eßer bool
15878bc019dSStefan Eßer bcl_leadingZeroes(void);
15950696a6eSStefan Eßer 
16078bc019dSStefan Eßer void
16178bc019dSStefan Eßer bcl_setLeadingZeroes(bool leadingZeroes);
16250696a6eSStefan Eßer 
163d101cdd6SStefan Eßer bool
164d101cdd6SStefan Eßer bcl_digitClamp(void);
165d101cdd6SStefan Eßer 
166d101cdd6SStefan Eßer void
167d101cdd6SStefan Eßer bcl_setDigitClamp(bool digitClamp);
168d101cdd6SStefan Eßer 
16978bc019dSStefan Eßer void
17078bc019dSStefan Eßer bcl_gc(void);
17150696a6eSStefan Eßer 
17278bc019dSStefan Eßer BclError
17378bc019dSStefan Eßer bcl_pushContext(BclContext ctxt);
17450696a6eSStefan Eßer 
17578bc019dSStefan Eßer void
17678bc019dSStefan Eßer bcl_popContext(void);
17750696a6eSStefan Eßer 
17878bc019dSStefan Eßer BclContext
17978bc019dSStefan Eßer bcl_context(void);
18050696a6eSStefan Eßer 
18178bc019dSStefan Eßer BclContext
18278bc019dSStefan Eßer bcl_ctxt_create(void);
18350696a6eSStefan Eßer 
18478bc019dSStefan Eßer void
18578bc019dSStefan Eßer bcl_ctxt_free(BclContext ctxt);
18650696a6eSStefan Eßer 
18778bc019dSStefan Eßer void
18878bc019dSStefan Eßer bcl_ctxt_freeNums(BclContext ctxt);
18950696a6eSStefan Eßer 
19078bc019dSStefan Eßer size_t
19178bc019dSStefan Eßer bcl_ctxt_scale(BclContext ctxt);
19250696a6eSStefan Eßer 
19378bc019dSStefan Eßer void
19478bc019dSStefan Eßer bcl_ctxt_setScale(BclContext ctxt, size_t scale);
19550696a6eSStefan Eßer 
19678bc019dSStefan Eßer size_t
19778bc019dSStefan Eßer bcl_ctxt_ibase(BclContext ctxt);
19878bc019dSStefan Eßer 
19978bc019dSStefan Eßer void
20078bc019dSStefan Eßer bcl_ctxt_setIbase(BclContext ctxt, size_t ibase);
20178bc019dSStefan Eßer 
20278bc019dSStefan Eßer size_t
20378bc019dSStefan Eßer bcl_ctxt_obase(BclContext ctxt);
20478bc019dSStefan Eßer 
20578bc019dSStefan Eßer void
20678bc019dSStefan Eßer bcl_ctxt_setObase(BclContext ctxt, size_t obase);
20778bc019dSStefan Eßer 
20878bc019dSStefan Eßer BclError
20978bc019dSStefan Eßer bcl_err(BclNumber n);
21078bc019dSStefan Eßer 
21178bc019dSStefan Eßer BclNumber
21278bc019dSStefan Eßer bcl_num_create(void);
21378bc019dSStefan Eßer 
21478bc019dSStefan Eßer void
21578bc019dSStefan Eßer bcl_num_free(BclNumber n);
21678bc019dSStefan Eßer 
21778bc019dSStefan Eßer bool
21878bc019dSStefan Eßer bcl_num_neg(BclNumber n);
21978bc019dSStefan Eßer 
22078bc019dSStefan Eßer void
22178bc019dSStefan Eßer bcl_num_setNeg(BclNumber n, bool neg);
22278bc019dSStefan Eßer 
22378bc019dSStefan Eßer size_t
22478bc019dSStefan Eßer bcl_num_scale(BclNumber n);
22578bc019dSStefan Eßer 
22678bc019dSStefan Eßer BclError
22778bc019dSStefan Eßer bcl_num_setScale(BclNumber n, size_t scale);
22878bc019dSStefan Eßer 
22978bc019dSStefan Eßer size_t
23078bc019dSStefan Eßer bcl_num_len(BclNumber n);
23178bc019dSStefan Eßer 
23278bc019dSStefan Eßer BclError
23378bc019dSStefan Eßer bcl_copy(BclNumber d, BclNumber s);
23478bc019dSStefan Eßer 
23578bc019dSStefan Eßer BclNumber
23678bc019dSStefan Eßer bcl_dup(BclNumber s);
23778bc019dSStefan Eßer 
23878bc019dSStefan Eßer BclError
23978bc019dSStefan Eßer bcl_bigdig(BclNumber n, BclBigDig* result);
24078bc019dSStefan Eßer 
241175a4d10SStefan Eßer BclError
242175a4d10SStefan Eßer bcl_bigdig_keep(BclNumber n, BclBigDig* result);
243175a4d10SStefan Eßer 
24478bc019dSStefan Eßer BclNumber
24578bc019dSStefan Eßer bcl_bigdig2num(BclBigDig val);
24678bc019dSStefan Eßer 
24778bc019dSStefan Eßer BclNumber
24878bc019dSStefan Eßer bcl_add(BclNumber a, BclNumber b);
24978bc019dSStefan Eßer 
25078bc019dSStefan Eßer BclNumber
251175a4d10SStefan Eßer bcl_add_keep(BclNumber a, BclNumber b);
252175a4d10SStefan Eßer 
253175a4d10SStefan Eßer BclNumber
25478bc019dSStefan Eßer bcl_sub(BclNumber a, BclNumber b);
25578bc019dSStefan Eßer 
25678bc019dSStefan Eßer BclNumber
257175a4d10SStefan Eßer bcl_sub_keep(BclNumber a, BclNumber b);
258175a4d10SStefan Eßer 
259175a4d10SStefan Eßer BclNumber
26078bc019dSStefan Eßer bcl_mul(BclNumber a, BclNumber b);
26178bc019dSStefan Eßer 
26278bc019dSStefan Eßer BclNumber
263175a4d10SStefan Eßer bcl_mul_keep(BclNumber a, BclNumber b);
264175a4d10SStefan Eßer 
265175a4d10SStefan Eßer BclNumber
26678bc019dSStefan Eßer bcl_div(BclNumber a, BclNumber b);
26778bc019dSStefan Eßer 
26878bc019dSStefan Eßer BclNumber
269175a4d10SStefan Eßer bcl_div_keep(BclNumber a, BclNumber b);
270175a4d10SStefan Eßer 
271175a4d10SStefan Eßer BclNumber
27278bc019dSStefan Eßer bcl_mod(BclNumber a, BclNumber b);
27378bc019dSStefan Eßer 
27478bc019dSStefan Eßer BclNumber
275175a4d10SStefan Eßer bcl_mod_keep(BclNumber a, BclNumber b);
276175a4d10SStefan Eßer 
277175a4d10SStefan Eßer BclNumber
27878bc019dSStefan Eßer bcl_pow(BclNumber a, BclNumber b);
27978bc019dSStefan Eßer 
28078bc019dSStefan Eßer BclNumber
281175a4d10SStefan Eßer bcl_pow_keep(BclNumber a, BclNumber b);
282175a4d10SStefan Eßer 
283175a4d10SStefan Eßer BclNumber
28478bc019dSStefan Eßer bcl_lshift(BclNumber a, BclNumber b);
28578bc019dSStefan Eßer 
28678bc019dSStefan Eßer BclNumber
287175a4d10SStefan Eßer bcl_lshift_keep(BclNumber a, BclNumber b);
288175a4d10SStefan Eßer 
289175a4d10SStefan Eßer BclNumber
29078bc019dSStefan Eßer bcl_rshift(BclNumber a, BclNumber b);
29178bc019dSStefan Eßer 
29278bc019dSStefan Eßer BclNumber
293175a4d10SStefan Eßer bcl_rshift_keep(BclNumber a, BclNumber b);
294175a4d10SStefan Eßer 
295175a4d10SStefan Eßer BclNumber
29678bc019dSStefan Eßer bcl_sqrt(BclNumber a);
29778bc019dSStefan Eßer 
298175a4d10SStefan Eßer BclNumber
299175a4d10SStefan Eßer bcl_sqrt_keep(BclNumber a);
300175a4d10SStefan Eßer 
30178bc019dSStefan Eßer BclError
30278bc019dSStefan Eßer bcl_divmod(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
30378bc019dSStefan Eßer 
304175a4d10SStefan Eßer BclError
305175a4d10SStefan Eßer bcl_divmod_keep(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
306175a4d10SStefan Eßer 
30778bc019dSStefan Eßer BclNumber
30878bc019dSStefan Eßer bcl_modexp(BclNumber a, BclNumber b, BclNumber c);
30978bc019dSStefan Eßer 
310175a4d10SStefan Eßer BclNumber
311175a4d10SStefan Eßer bcl_modexp_keep(BclNumber a, BclNumber b, BclNumber c);
312175a4d10SStefan Eßer 
31378bc019dSStefan Eßer ssize_t
31478bc019dSStefan Eßer bcl_cmp(BclNumber a, BclNumber b);
31578bc019dSStefan Eßer 
31678bc019dSStefan Eßer void
31778bc019dSStefan Eßer bcl_zero(BclNumber n);
31878bc019dSStefan Eßer 
31978bc019dSStefan Eßer void
32078bc019dSStefan Eßer bcl_one(BclNumber n);
32178bc019dSStefan Eßer 
32278bc019dSStefan Eßer BclNumber
32378bc019dSStefan Eßer bcl_parse(const char* restrict val);
32478bc019dSStefan Eßer 
32578bc019dSStefan Eßer char*
32678bc019dSStefan Eßer bcl_string(BclNumber n);
32778bc019dSStefan Eßer 
328175a4d10SStefan Eßer char*
329175a4d10SStefan Eßer bcl_string_keep(BclNumber n);
330175a4d10SStefan Eßer 
33178bc019dSStefan Eßer BclNumber
33278bc019dSStefan Eßer bcl_irand(BclNumber a);
33378bc019dSStefan Eßer 
33478bc019dSStefan Eßer BclNumber
335175a4d10SStefan Eßer bcl_irand_keep(BclNumber a);
336175a4d10SStefan Eßer 
337175a4d10SStefan Eßer BclNumber
33878bc019dSStefan Eßer bcl_frand(size_t places);
33978bc019dSStefan Eßer 
34078bc019dSStefan Eßer BclNumber
34178bc019dSStefan Eßer bcl_ifrand(BclNumber a, size_t places);
34278bc019dSStefan Eßer 
343175a4d10SStefan Eßer BclNumber
344175a4d10SStefan Eßer bcl_ifrand_keep(BclNumber a, size_t places);
345175a4d10SStefan Eßer 
34678bc019dSStefan Eßer BclError
34778bc019dSStefan Eßer bcl_rand_seedWithNum(BclNumber n);
34878bc019dSStefan Eßer 
34978bc019dSStefan Eßer BclError
350175a4d10SStefan Eßer bcl_rand_seedWithNum_keep(BclNumber n);
351175a4d10SStefan Eßer 
352175a4d10SStefan Eßer BclError
35378bc019dSStefan Eßer bcl_rand_seed(unsigned char seed[BCL_SEED_SIZE]);
35478bc019dSStefan Eßer 
35578bc019dSStefan Eßer void
35678bc019dSStefan Eßer bcl_rand_reseed(void);
35778bc019dSStefan Eßer 
35878bc019dSStefan Eßer BclNumber
35978bc019dSStefan Eßer bcl_rand_seed2num(void);
36078bc019dSStefan Eßer 
36178bc019dSStefan Eßer BclRandInt
36278bc019dSStefan Eßer bcl_rand_int(void);
36378bc019dSStefan Eßer 
36478bc019dSStefan Eßer BclRandInt
36578bc019dSStefan Eßer bcl_rand_bounded(BclRandInt bound);
36650696a6eSStefan Eßer 
3677e5c51e5SStefan Eßer #endif // BC_ENABLE_LIBRARY
3687e5c51e5SStefan Eßer 
36950696a6eSStefan Eßer #endif // BC_BCL_H
370