mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-21 18:27:22 +00:00
contrib/bc: update to version 6.4.0
This version contains a fix for an issue that can affect complex bc scripts that use multiple read() functions that receive input from an interactive user. The same value could be returned multiple times. MFC after: 2 weeks
This commit is contained in:
parent
cc0fe048ec
commit
175a4d1042
|
@ -536,7 +536,6 @@ clean:%%CLEAN_PREREQS%%
|
|||
@$(RM) -f $(BC_HELP_C) $(BC_HELP_O)
|
||||
@$(RM) -f $(DC_HELP_C) $(DC_HELP_O)
|
||||
@$(RM) -fr vs/bin/ vs/lib/
|
||||
@$(RM) -f $(BCL_PC)
|
||||
|
||||
clean_benchmarks:
|
||||
@printf 'Cleaning benchmarks...\n'
|
||||
|
@ -550,6 +549,7 @@ clean_config: clean clean_benchmarks
|
|||
@$(RM) -f $(BC_MD) $(BC_MANPAGE)
|
||||
@$(RM) -f $(DC_MD) $(DC_MANPAGE)
|
||||
@$(RM) -f compile_commands.json
|
||||
@$(RM) -f $(BCL_PC)
|
||||
|
||||
clean_coverage:
|
||||
@printf 'Cleaning coverage files...\n'
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
# News
|
||||
|
||||
## 6.4.0
|
||||
|
||||
This is a production release that fixes a `read()`/`?` bug and adds features to
|
||||
`bcl`.
|
||||
|
||||
The bug was that multiple read calls could repeat old data.
|
||||
|
||||
The new features in `bcl` are functions to preserve `BclNumber` arguments and
|
||||
not free them.
|
||||
|
||||
***WARNING for `bcl` Users***: The `bcl_rand_seedWithNum()` function used to not
|
||||
consume its arguments. Now it does. This change could have made this version
|
||||
`7.0.0`, but I'm 99.9% confident that there are no `bcl` users, or if there are,
|
||||
they probably don't use the PRNG. So I took a risk and didn't update the major
|
||||
version.
|
||||
|
||||
`bcl` now includes more capacity to check for invalid numbers when built to run
|
||||
under Valgrind.
|
||||
|
||||
## 6.3.1
|
||||
|
||||
This is a production release that fixes a `bc` dependency loop for minimal
|
||||
|
|
|
@ -1801,7 +1801,7 @@ if [ "$library" -ne 0 ]; then
|
|||
contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
|
||||
contents=$(replace "$contents" "VERSION" "$version")
|
||||
|
||||
printf '%s\n' "$contents" > "./bcl.pc"
|
||||
printf '%s\n' "$contents" > "$scriptdir/bcl.pc"
|
||||
|
||||
pkg_config_install="\$(SAFE_INSTALL) \$(PC_INSTALL_ARGS) \"\$(BCL_PC)\" \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
|
||||
pkg_config_uninstall="\$(RM) -f \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#ifndef BC_BCL_H
|
||||
#define BC_BCL_H
|
||||
|
||||
// TODO: Add a generation index when building with Valgrind to check for
|
||||
// use-after-free's or double frees.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
@ -238,42 +241,78 @@ bcl_dup(BclNumber s);
|
|||
BclError
|
||||
bcl_bigdig(BclNumber n, BclBigDig* result);
|
||||
|
||||
BclError
|
||||
bcl_bigdig_keep(BclNumber n, BclBigDig* result);
|
||||
|
||||
BclNumber
|
||||
bcl_bigdig2num(BclBigDig val);
|
||||
|
||||
BclNumber
|
||||
bcl_add(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_add_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_sub(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_sub_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_mul(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_mul_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_div(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_div_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_mod(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_mod_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_pow(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_pow_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_lshift(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_lshift_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_rshift(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_rshift_keep(BclNumber a, BclNumber b);
|
||||
|
||||
BclNumber
|
||||
bcl_sqrt(BclNumber a);
|
||||
|
||||
BclNumber
|
||||
bcl_sqrt_keep(BclNumber a);
|
||||
|
||||
BclError
|
||||
bcl_divmod(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
|
||||
|
||||
BclError
|
||||
bcl_divmod_keep(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
|
||||
|
||||
BclNumber
|
||||
bcl_modexp(BclNumber a, BclNumber b, BclNumber c);
|
||||
|
||||
BclNumber
|
||||
bcl_modexp_keep(BclNumber a, BclNumber b, BclNumber c);
|
||||
|
||||
ssize_t
|
||||
bcl_cmp(BclNumber a, BclNumber b);
|
||||
|
||||
|
@ -289,18 +328,30 @@ bcl_parse(const char* restrict val);
|
|||
char*
|
||||
bcl_string(BclNumber n);
|
||||
|
||||
char*
|
||||
bcl_string_keep(BclNumber n);
|
||||
|
||||
BclNumber
|
||||
bcl_irand(BclNumber a);
|
||||
|
||||
BclNumber
|
||||
bcl_irand_keep(BclNumber a);
|
||||
|
||||
BclNumber
|
||||
bcl_frand(size_t places);
|
||||
|
||||
BclNumber
|
||||
bcl_ifrand(BclNumber a, size_t places);
|
||||
|
||||
BclNumber
|
||||
bcl_ifrand_keep(BclNumber a, size_t places);
|
||||
|
||||
BclError
|
||||
bcl_rand_seedWithNum(BclNumber n);
|
||||
|
||||
BclError
|
||||
bcl_rand_seedWithNum_keep(BclNumber n);
|
||||
|
||||
BclError
|
||||
bcl_rand_seed(unsigned char seed[BCL_SEED_SIZE]);
|
||||
|
||||
|
|
|
@ -47,6 +47,145 @@
|
|||
#include <num.h>
|
||||
#include <vm.h>
|
||||
|
||||
#if BC_ENABLE_MEMCHECK
|
||||
|
||||
/**
|
||||
* A typedef for Valgrind builds. This is to add a generation index for error
|
||||
* checking.
|
||||
*/
|
||||
typedef struct BclNum
|
||||
{
|
||||
/// The number.
|
||||
BcNum n;
|
||||
|
||||
/// The generation index.
|
||||
size_t gen_idx;
|
||||
|
||||
} BclNum;
|
||||
|
||||
/**
|
||||
* Clears the generation byte in a BclNumber and returns the value.
|
||||
* @param n The BclNumber.
|
||||
* @return The value of the index.
|
||||
*/
|
||||
#define BCL_NO_GEN(n) \
|
||||
((n).i & ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)))
|
||||
|
||||
/**
|
||||
* Gets the generation index in a BclNumber.
|
||||
* @param n The BclNumber.
|
||||
* @return The generation index.
|
||||
*/
|
||||
#define BCL_GET_GEN(n) ((n).i >> ((sizeof(size_t) - 1) * CHAR_BIT))
|
||||
|
||||
/**
|
||||
* Turns a BclNumber into a BcNum.
|
||||
* @param c The context.
|
||||
* @param n The BclNumber.
|
||||
*/
|
||||
#define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, BCL_NO_GEN(n)))
|
||||
|
||||
/**
|
||||
* Clears the generation index top byte in the BclNumber.
|
||||
* @param n The BclNumber.
|
||||
*/
|
||||
#define BCL_CLEAR_GEN(n) \
|
||||
do \
|
||||
{ \
|
||||
(n).i &= ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define BCL_CHECK_NUM_GEN(c, bn) \
|
||||
do \
|
||||
{ \
|
||||
size_t gen_ = BCL_GET_GEN(bn); \
|
||||
BclNum* ptr_ = BCL_NUM(c, bn); \
|
||||
if (BCL_NUM_ARRAY(ptr_) == NULL) \
|
||||
{ \
|
||||
bcl_nonexistentNum(); \
|
||||
} \
|
||||
if (gen_ != ptr_->gen_idx) \
|
||||
{ \
|
||||
bcl_invalidGeneration(); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define BCL_CHECK_NUM_VALID(c, bn) \
|
||||
do \
|
||||
{ \
|
||||
size_t idx_ = BCL_NO_GEN(bn); \
|
||||
if ((c)->nums.len <= idx_) \
|
||||
{ \
|
||||
bcl_numIdxOutOfRange(); \
|
||||
} \
|
||||
BCL_CHECK_NUM_GEN(c, bn); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
* Returns the limb array of the number.
|
||||
* @param bn The number.
|
||||
* @return The limb array.
|
||||
*/
|
||||
#define BCL_NUM_ARRAY(bn) ((bn)->n.num)
|
||||
|
||||
/**
|
||||
* Returns the limb array of the number for a non-pointer.
|
||||
* @param bn The number.
|
||||
* @return The limb array.
|
||||
*/
|
||||
#define BCL_NUM_ARRAY_NP(bn) ((bn).n.num)
|
||||
|
||||
/**
|
||||
* Returns the BcNum pointer.
|
||||
* @param bn The number.
|
||||
* @return The BcNum pointer.
|
||||
*/
|
||||
#define BCL_NUM_NUM(bn) (&(bn)->n)
|
||||
|
||||
/**
|
||||
* Returns the BcNum pointer for a non-pointer.
|
||||
* @param bn The number.
|
||||
* @return The BcNum pointer.
|
||||
*/
|
||||
#define BCL_NUM_NUM_NP(bn) (&(bn).n)
|
||||
|
||||
// These functions only abort. They exist to give developers some idea of what
|
||||
// went wrong when bugs are found, if they look at the Valgrind stack trace.
|
||||
|
||||
BC_NORETURN void
|
||||
bcl_invalidGeneration(void);
|
||||
|
||||
BC_NORETURN void
|
||||
bcl_nonexistentNum(void);
|
||||
|
||||
BC_NORETURN void
|
||||
bcl_numIdxOutOfRange(void);
|
||||
|
||||
#else // BC_ENABLE_MEMCHECK
|
||||
|
||||
/**
|
||||
* A typedef for non-Valgrind builds.
|
||||
*/
|
||||
typedef BcNum BclNum;
|
||||
|
||||
#define BCL_NO_GEN(n) ((n).i)
|
||||
#define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, (n).i))
|
||||
#define BCL_CLEAR_GEN(n) ((void) (n))
|
||||
|
||||
#define BCL_CHECK_NUM_GEN(c, bn)
|
||||
#define BCL_CHECK_NUM_VALID(c, n)
|
||||
|
||||
#define BCL_NUM_ARRAY(bn) ((bn)->num)
|
||||
#define BCL_NUM_ARRAY_NP(bn) ((bn).num)
|
||||
|
||||
#define BCL_NUM_NUM(bn) (bn)
|
||||
#define BCL_NUM_NUM_NP(bn) (&(bn))
|
||||
|
||||
#endif // BC_ENABLE_MEMCHECK
|
||||
|
||||
/**
|
||||
* A header that sets a jump.
|
||||
* @param vm The thread data.
|
||||
|
@ -88,19 +227,19 @@
|
|||
* idx.
|
||||
* @param c The context.
|
||||
* @param e The error.
|
||||
* @param n The number.
|
||||
* @param bn The number.
|
||||
* @param idx The idx to set as the return value.
|
||||
*/
|
||||
#define BC_MAYBE_SETUP(c, e, n, idx) \
|
||||
do \
|
||||
{ \
|
||||
if (BC_ERR((e) != BCL_ERROR_NONE)) \
|
||||
{ \
|
||||
if ((n).num != NULL) bc_num_free(&(n)); \
|
||||
idx.i = 0 - (size_t) (e); \
|
||||
} \
|
||||
else idx = bcl_num_insert(c, &(n)); \
|
||||
} \
|
||||
#define BC_MAYBE_SETUP(c, e, bn, idx) \
|
||||
do \
|
||||
{ \
|
||||
if (BC_ERR((e) != BCL_ERROR_NONE)) \
|
||||
{ \
|
||||
if (BCL_NUM_ARRAY_NP(bn) != NULL) bc_num_free(BCL_NUM_NUM_NP(bn)); \
|
||||
idx.i = 0 - (size_t) (e); \
|
||||
} \
|
||||
else idx = bcl_num_insert(c, &(bn)); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
|
@ -108,17 +247,17 @@
|
|||
* is bad.
|
||||
* @param c The context.
|
||||
*/
|
||||
#define BC_CHECK_CTXT(vm, c) \
|
||||
do \
|
||||
{ \
|
||||
c = bcl_contextHelper(vm); \
|
||||
if (BC_ERR(c == NULL)) \
|
||||
{ \
|
||||
BclNumber n_num; \
|
||||
n_num.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
|
||||
return n_num; \
|
||||
} \
|
||||
} \
|
||||
#define BC_CHECK_CTXT(vm, c) \
|
||||
do \
|
||||
{ \
|
||||
c = bcl_contextHelper(vm); \
|
||||
if (BC_ERR(c == NULL)) \
|
||||
{ \
|
||||
BclNumber n_num_; \
|
||||
n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
|
||||
return n_num_; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
|
@ -157,16 +296,18 @@
|
|||
#define BC_CHECK_NUM(c, n) \
|
||||
do \
|
||||
{ \
|
||||
if (BC_ERR((n).i >= (c)->nums.len)) \
|
||||
size_t no_gen_ = BCL_NO_GEN(n); \
|
||||
if (BC_ERR(no_gen_ >= (c)->nums.len)) \
|
||||
{ \
|
||||
if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \
|
||||
else \
|
||||
{ \
|
||||
BclNumber n_num; \
|
||||
n_num.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \
|
||||
return n_num; \
|
||||
BclNumber n_num_; \
|
||||
n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \
|
||||
return n_num_; \
|
||||
} \
|
||||
} \
|
||||
BCL_CHECK_NUM_GEN(c, n); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
@ -181,7 +322,8 @@
|
|||
#define BC_CHECK_NUM_ERR(c, n) \
|
||||
do \
|
||||
{ \
|
||||
if (BC_ERR((n).i >= (c)->nums.len)) \
|
||||
size_t no_gen_ = BCL_NO_GEN(n); \
|
||||
if (BC_ERR(no_gen_ >= (c)->nums.len)) \
|
||||
{ \
|
||||
if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) \
|
||||
{ \
|
||||
|
@ -189,17 +331,25 @@
|
|||
} \
|
||||
else return BCL_ERROR_INVALID_NUM; \
|
||||
} \
|
||||
BCL_CHECK_NUM_GEN(c, n); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
//clang-format on
|
||||
|
||||
/**
|
||||
* Turns a BclNumber into a BcNum.
|
||||
* Grows the context's nums array if necessary.
|
||||
* @param c The context.
|
||||
* @param n The BclNumber.
|
||||
*/
|
||||
#define BC_NUM(c, n) ((BcNum*) bc_vec_item(&(c)->nums, (n).i))
|
||||
#define BCL_GROW_NUMS(c) \
|
||||
do \
|
||||
{ \
|
||||
if ((c)->free_nums.len == 0) \
|
||||
{ \
|
||||
bc_vec_grow(&((c)->nums), 1); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
* Frees a BcNum for bcl. This is a destructor.
|
||||
|
|
|
@ -904,148 +904,82 @@ extern const char bc_program_esc_seqs[];
|
|||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_PROG_LBLS \
|
||||
static const void* const bc_program_inst_lbls[] = { \
|
||||
&&lbl_BC_INST_NEG, \
|
||||
&&lbl_BC_INST_BOOL_NOT, \
|
||||
&&lbl_BC_INST_TRUNC, \
|
||||
&&lbl_BC_INST_POWER, \
|
||||
&&lbl_BC_INST_MULTIPLY, \
|
||||
&&lbl_BC_INST_DIVIDE, \
|
||||
&&lbl_BC_INST_MODULUS, \
|
||||
&&lbl_BC_INST_PLUS, \
|
||||
&&lbl_BC_INST_MINUS, \
|
||||
&&lbl_BC_INST_PLACES, \
|
||||
&&lbl_BC_INST_LSHIFT, \
|
||||
&&lbl_BC_INST_RSHIFT, \
|
||||
&&lbl_BC_INST_REL_EQ, \
|
||||
&&lbl_BC_INST_REL_LE, \
|
||||
&&lbl_BC_INST_REL_GE, \
|
||||
&&lbl_BC_INST_REL_NE, \
|
||||
&&lbl_BC_INST_REL_LT, \
|
||||
&&lbl_BC_INST_REL_GT, \
|
||||
&&lbl_BC_INST_BOOL_OR, \
|
||||
&&lbl_BC_INST_BOOL_AND, \
|
||||
&&lbl_BC_INST_ASSIGN_NO_VAL, \
|
||||
&&lbl_BC_INST_NUM, \
|
||||
&&lbl_BC_INST_VAR, \
|
||||
&&lbl_BC_INST_ARRAY_ELEM, \
|
||||
&&lbl_BC_INST_ARRAY, \
|
||||
&&lbl_BC_INST_ZERO, \
|
||||
&&lbl_BC_INST_ONE, \
|
||||
&&lbl_BC_INST_IBASE, \
|
||||
&&lbl_BC_INST_OBASE, \
|
||||
&&lbl_BC_INST_SCALE, \
|
||||
&&lbl_BC_INST_SEED, \
|
||||
&&lbl_BC_INST_LENGTH, \
|
||||
&&lbl_BC_INST_SCALE_FUNC, \
|
||||
&&lbl_BC_INST_SQRT, \
|
||||
&&lbl_BC_INST_ABS, \
|
||||
&&lbl_BC_INST_IS_NUMBER, \
|
||||
&&lbl_BC_INST_IS_STRING, \
|
||||
&&lbl_BC_INST_IRAND, \
|
||||
&&lbl_BC_INST_ASCIIFY, \
|
||||
&&lbl_BC_INST_READ, \
|
||||
&&lbl_BC_INST_RAND, \
|
||||
&&lbl_BC_INST_MAXIBASE, \
|
||||
&&lbl_BC_INST_MAXOBASE, \
|
||||
&&lbl_BC_INST_MAXSCALE, \
|
||||
&&lbl_BC_INST_MAXRAND, \
|
||||
&&lbl_BC_INST_LINE_LENGTH, \
|
||||
&&lbl_BC_INST_LEADING_ZERO, \
|
||||
&&lbl_BC_INST_PRINT, \
|
||||
&&lbl_BC_INST_PRINT_POP, \
|
||||
&&lbl_BC_INST_STR, \
|
||||
&&lbl_BC_INST_POP, \
|
||||
&&lbl_BC_INST_SWAP, \
|
||||
&&lbl_BC_INST_MODEXP, \
|
||||
&&lbl_BC_INST_DIVMOD, \
|
||||
&&lbl_BC_INST_PRINT_STREAM, \
|
||||
&&lbl_BC_INST_EXTENDED_REGISTERS, \
|
||||
&&lbl_BC_INST_POP_EXEC, \
|
||||
&&lbl_BC_INST_EXECUTE, \
|
||||
&&lbl_BC_INST_EXEC_COND, \
|
||||
&&lbl_BC_INST_PRINT_STACK, \
|
||||
&&lbl_BC_INST_CLEAR_STACK, \
|
||||
&&lbl_BC_INST_REG_STACK_LEN, \
|
||||
&&lbl_BC_INST_STACK_LEN, \
|
||||
&&lbl_BC_INST_DUPLICATE, \
|
||||
&&lbl_BC_INST_LOAD, \
|
||||
&&lbl_BC_INST_PUSH_VAR, \
|
||||
&&lbl_BC_INST_PUSH_TO_VAR, \
|
||||
&&lbl_BC_INST_QUIT, \
|
||||
&&lbl_BC_INST_NQUIT, \
|
||||
&&lbl_BC_INST_EXEC_STACK_LEN, \
|
||||
&&lbl_BC_INST_INVALID, \
|
||||
#define BC_PROG_LBLS \
|
||||
static const void* const bc_program_inst_lbls[] = { \
|
||||
&&lbl_BC_INST_NEG, &&lbl_BC_INST_BOOL_NOT, \
|
||||
&&lbl_BC_INST_TRUNC, &&lbl_BC_INST_POWER, \
|
||||
&&lbl_BC_INST_MULTIPLY, &&lbl_BC_INST_DIVIDE, \
|
||||
&&lbl_BC_INST_MODULUS, &&lbl_BC_INST_PLUS, \
|
||||
&&lbl_BC_INST_MINUS, &&lbl_BC_INST_PLACES, \
|
||||
&&lbl_BC_INST_LSHIFT, &&lbl_BC_INST_RSHIFT, \
|
||||
&&lbl_BC_INST_REL_EQ, &&lbl_BC_INST_REL_LE, \
|
||||
&&lbl_BC_INST_REL_GE, &&lbl_BC_INST_REL_NE, \
|
||||
&&lbl_BC_INST_REL_LT, &&lbl_BC_INST_REL_GT, \
|
||||
&&lbl_BC_INST_BOOL_OR, &&lbl_BC_INST_BOOL_AND, \
|
||||
&&lbl_BC_INST_ASSIGN_NO_VAL, &&lbl_BC_INST_NUM, \
|
||||
&&lbl_BC_INST_VAR, &&lbl_BC_INST_ARRAY_ELEM, \
|
||||
&&lbl_BC_INST_ARRAY, &&lbl_BC_INST_ZERO, \
|
||||
&&lbl_BC_INST_ONE, &&lbl_BC_INST_IBASE, \
|
||||
&&lbl_BC_INST_OBASE, &&lbl_BC_INST_SCALE, \
|
||||
&&lbl_BC_INST_SEED, &&lbl_BC_INST_LENGTH, \
|
||||
&&lbl_BC_INST_SCALE_FUNC, &&lbl_BC_INST_SQRT, \
|
||||
&&lbl_BC_INST_ABS, &&lbl_BC_INST_IS_NUMBER, \
|
||||
&&lbl_BC_INST_IS_STRING, &&lbl_BC_INST_IRAND, \
|
||||
&&lbl_BC_INST_ASCIIFY, &&lbl_BC_INST_READ, \
|
||||
&&lbl_BC_INST_RAND, &&lbl_BC_INST_MAXIBASE, \
|
||||
&&lbl_BC_INST_MAXOBASE, &&lbl_BC_INST_MAXSCALE, \
|
||||
&&lbl_BC_INST_MAXRAND, &&lbl_BC_INST_LINE_LENGTH, \
|
||||
&&lbl_BC_INST_LEADING_ZERO, &&lbl_BC_INST_PRINT, \
|
||||
&&lbl_BC_INST_PRINT_POP, &&lbl_BC_INST_STR, \
|
||||
&&lbl_BC_INST_POP, &&lbl_BC_INST_SWAP, \
|
||||
&&lbl_BC_INST_MODEXP, &&lbl_BC_INST_DIVMOD, \
|
||||
&&lbl_BC_INST_PRINT_STREAM, &&lbl_BC_INST_EXTENDED_REGISTERS, \
|
||||
&&lbl_BC_INST_POP_EXEC, &&lbl_BC_INST_EXECUTE, \
|
||||
&&lbl_BC_INST_EXEC_COND, &&lbl_BC_INST_PRINT_STACK, \
|
||||
&&lbl_BC_INST_CLEAR_STACK, &&lbl_BC_INST_REG_STACK_LEN, \
|
||||
&&lbl_BC_INST_STACK_LEN, &&lbl_BC_INST_DUPLICATE, \
|
||||
&&lbl_BC_INST_LOAD, &&lbl_BC_INST_PUSH_VAR, \
|
||||
&&lbl_BC_INST_PUSH_TO_VAR, &&lbl_BC_INST_QUIT, \
|
||||
&&lbl_BC_INST_NQUIT, &&lbl_BC_INST_EXEC_STACK_LEN, \
|
||||
&&lbl_BC_INST_INVALID, \
|
||||
}
|
||||
|
||||
#else // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_PROG_LBLS \
|
||||
static const void* const bc_program_inst_lbls[] = { \
|
||||
&&lbl_BC_INST_NEG, \
|
||||
&&lbl_BC_INST_BOOL_NOT, \
|
||||
&&lbl_BC_INST_POWER, \
|
||||
&&lbl_BC_INST_MULTIPLY, \
|
||||
&&lbl_BC_INST_DIVIDE, \
|
||||
&&lbl_BC_INST_MODULUS, \
|
||||
&&lbl_BC_INST_PLUS, \
|
||||
&&lbl_BC_INST_MINUS, \
|
||||
&&lbl_BC_INST_REL_EQ, \
|
||||
&&lbl_BC_INST_REL_LE, \
|
||||
&&lbl_BC_INST_REL_GE, \
|
||||
&&lbl_BC_INST_REL_NE, \
|
||||
&&lbl_BC_INST_REL_LT, \
|
||||
&&lbl_BC_INST_REL_GT, \
|
||||
&&lbl_BC_INST_BOOL_OR, \
|
||||
&&lbl_BC_INST_BOOL_AND, \
|
||||
&&lbl_BC_INST_ASSIGN_NO_VAL, \
|
||||
&&lbl_BC_INST_NUM, \
|
||||
&&lbl_BC_INST_VAR, \
|
||||
&&lbl_BC_INST_ARRAY_ELEM, \
|
||||
&&lbl_BC_INST_ARRAY, \
|
||||
&&lbl_BC_INST_ZERO, \
|
||||
&&lbl_BC_INST_ONE, \
|
||||
&&lbl_BC_INST_IBASE, \
|
||||
&&lbl_BC_INST_OBASE, \
|
||||
&&lbl_BC_INST_SCALE, \
|
||||
&&lbl_BC_INST_LENGTH, \
|
||||
&&lbl_BC_INST_SCALE_FUNC, \
|
||||
&&lbl_BC_INST_SQRT, \
|
||||
&&lbl_BC_INST_ABS, \
|
||||
&&lbl_BC_INST_IS_NUMBER, \
|
||||
&&lbl_BC_INST_IS_STRING, \
|
||||
&&lbl_BC_INST_ASCIIFY, \
|
||||
&&lbl_BC_INST_READ, \
|
||||
&&lbl_BC_INST_MAXIBASE, \
|
||||
&&lbl_BC_INST_MAXOBASE, \
|
||||
&&lbl_BC_INST_MAXSCALE, \
|
||||
&&lbl_BC_INST_LINE_LENGTH, \
|
||||
&&lbl_BC_INST_LEADING_ZERO, \
|
||||
&&lbl_BC_INST_PRINT, \
|
||||
&&lbl_BC_INST_PRINT_POP, \
|
||||
&&lbl_BC_INST_STR, \
|
||||
&&lbl_BC_INST_POP, \
|
||||
&&lbl_BC_INST_SWAP, \
|
||||
&&lbl_BC_INST_MODEXP, \
|
||||
&&lbl_BC_INST_DIVMOD, \
|
||||
&&lbl_BC_INST_PRINT_STREAM, \
|
||||
&&lbl_BC_INST_EXTENDED_REGISTERS, \
|
||||
&&lbl_BC_INST_POP_EXEC, \
|
||||
&&lbl_BC_INST_EXECUTE, \
|
||||
&&lbl_BC_INST_EXEC_COND, \
|
||||
&&lbl_BC_INST_PRINT_STACK, \
|
||||
&&lbl_BC_INST_CLEAR_STACK, \
|
||||
&&lbl_BC_INST_REG_STACK_LEN, \
|
||||
&&lbl_BC_INST_STACK_LEN, \
|
||||
&&lbl_BC_INST_DUPLICATE, \
|
||||
&&lbl_BC_INST_LOAD, \
|
||||
&&lbl_BC_INST_PUSH_VAR, \
|
||||
&&lbl_BC_INST_PUSH_TO_VAR, \
|
||||
&&lbl_BC_INST_QUIT, \
|
||||
&&lbl_BC_INST_NQUIT, \
|
||||
&&lbl_BC_INST_EXEC_STACK_LEN, \
|
||||
&&lbl_BC_INST_INVALID, \
|
||||
#define BC_PROG_LBLS \
|
||||
static const void* const bc_program_inst_lbls[] = { \
|
||||
&&lbl_BC_INST_NEG, &&lbl_BC_INST_BOOL_NOT, \
|
||||
&&lbl_BC_INST_POWER, &&lbl_BC_INST_MULTIPLY, \
|
||||
&&lbl_BC_INST_DIVIDE, &&lbl_BC_INST_MODULUS, \
|
||||
&&lbl_BC_INST_PLUS, &&lbl_BC_INST_MINUS, \
|
||||
&&lbl_BC_INST_REL_EQ, &&lbl_BC_INST_REL_LE, \
|
||||
&&lbl_BC_INST_REL_GE, &&lbl_BC_INST_REL_NE, \
|
||||
&&lbl_BC_INST_REL_LT, &&lbl_BC_INST_REL_GT, \
|
||||
&&lbl_BC_INST_BOOL_OR, &&lbl_BC_INST_BOOL_AND, \
|
||||
&&lbl_BC_INST_ASSIGN_NO_VAL, &&lbl_BC_INST_NUM, \
|
||||
&&lbl_BC_INST_VAR, &&lbl_BC_INST_ARRAY_ELEM, \
|
||||
&&lbl_BC_INST_ARRAY, &&lbl_BC_INST_ZERO, \
|
||||
&&lbl_BC_INST_ONE, &&lbl_BC_INST_IBASE, \
|
||||
&&lbl_BC_INST_OBASE, &&lbl_BC_INST_SCALE, \
|
||||
&&lbl_BC_INST_LENGTH, &&lbl_BC_INST_SCALE_FUNC, \
|
||||
&&lbl_BC_INST_SQRT, &&lbl_BC_INST_ABS, \
|
||||
&&lbl_BC_INST_IS_NUMBER, &&lbl_BC_INST_IS_STRING, \
|
||||
&&lbl_BC_INST_ASCIIFY, &&lbl_BC_INST_READ, \
|
||||
&&lbl_BC_INST_MAXIBASE, &&lbl_BC_INST_MAXOBASE, \
|
||||
&&lbl_BC_INST_MAXSCALE, &&lbl_BC_INST_LINE_LENGTH, \
|
||||
&&lbl_BC_INST_LEADING_ZERO, &&lbl_BC_INST_PRINT, \
|
||||
&&lbl_BC_INST_PRINT_POP, &&lbl_BC_INST_STR, \
|
||||
&&lbl_BC_INST_POP, &&lbl_BC_INST_SWAP, \
|
||||
&&lbl_BC_INST_MODEXP, &&lbl_BC_INST_DIVMOD, \
|
||||
&&lbl_BC_INST_PRINT_STREAM, &&lbl_BC_INST_EXTENDED_REGISTERS, \
|
||||
&&lbl_BC_INST_POP_EXEC, &&lbl_BC_INST_EXECUTE, \
|
||||
&&lbl_BC_INST_EXEC_COND, &&lbl_BC_INST_PRINT_STACK, \
|
||||
&&lbl_BC_INST_CLEAR_STACK, &&lbl_BC_INST_REG_STACK_LEN, \
|
||||
&&lbl_BC_INST_STACK_LEN, &&lbl_BC_INST_DUPLICATE, \
|
||||
&&lbl_BC_INST_LOAD, &&lbl_BC_INST_PUSH_VAR, \
|
||||
&&lbl_BC_INST_PUSH_TO_VAR, &&lbl_BC_INST_QUIT, \
|
||||
&&lbl_BC_INST_NQUIT, &&lbl_BC_INST_EXEC_STACK_LEN, \
|
||||
&&lbl_BC_INST_INVALID, \
|
||||
}
|
||||
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
|
|
@ -37,6 +37,6 @@
|
|||
#define BC_VERSION_H
|
||||
|
||||
/// The current version.
|
||||
#define VERSION 6.3.1
|
||||
#define VERSION 6.4.0
|
||||
|
||||
#endif // BC_VERSION_H
|
||||
|
|
|
@ -560,9 +560,13 @@ typedef struct BcVm
|
|||
/// The vector for creating strings to pass to the client.
|
||||
BcVec out;
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
|
||||
/// The PRNG.
|
||||
BcRNG rng;
|
||||
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
/// The current error.
|
||||
BclError err;
|
||||
|
||||
|
|
|
@ -139,9 +139,14 @@ integers.
|
|||
.PP
|
||||
\f[B]char* bcl_string(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]char* bcl_string_keep(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_bigdig(BclNumber\f[R] \f[I]n\f[R]\f[B], BclBigDig
|
||||
*\f[R]\f[I]result\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_bigdig_keep(BclNumber\f[R] \f[I]n\f[R]\f[B], BclBigDig
|
||||
*\f[R]\f[I]result\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]\f[B]);\f[R]
|
||||
.SS Math
|
||||
.PP
|
||||
|
@ -150,35 +155,68 @@ These items allow clients to run math on numbers.
|
|||
\f[B]BclNumber bcl_add(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_add_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_sub(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_sub_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_mul(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_mul_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_div(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_div_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_mod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_mod_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_pow(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_pow_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_lshift(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_lshift_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_rshift(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_rshift_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_sqrt_keep(BclNumber\f[R] \f[I]a\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_divmod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R]
|
||||
\f[I]b\f[R]\f[B], BclNumber *\f[R]\f[I]c\f[R]\f[B], BclNumber
|
||||
*\f[R]\f[I]d\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_divmod_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber *\f[R]\f[I]c\f[R]\f[B],
|
||||
BclNumber *\f[R]\f[I]d\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_modexp(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber\f[R] \f[I]c\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_modexp_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber\f[R] \f[I]c\f[R]\f[B]);\f[R]
|
||||
.SS Miscellaneous
|
||||
.PP
|
||||
These items are miscellaneous.
|
||||
|
@ -209,14 +247,22 @@ generator in bcl(3).
|
|||
.PP
|
||||
\f[B]BclNumber bcl_irand(BclNumber\f[R] \f[I]a\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_irand_keep(BclNumber\f[R] \f[I]a\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_ifrand(BclNumber\f[R] \f[I]a\f[R]\f[B], size_t\f[R]
|
||||
\f[I]places\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclNumber bcl_ifrand_keep(BclNumber\f[R] \f[I]a\f[R]\f[B],
|
||||
size_t\f[R] \f[I]places\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R]
|
||||
\f[I]n\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_rand_seedWithNum_keep(BclNumber\f[R]
|
||||
\f[I]n\f[R]\f[B]);\f[R]
|
||||
.PP
|
||||
\f[B]BclError bcl_rand_seed(unsigned char\f[R]
|
||||
\f[I]seed\f[R]\f[B][\f[R]\f[I]BCL_SEED_SIZE\f[R]\f[B]]);\f[R]
|
||||
.PP
|
||||
|
@ -608,8 +654,9 @@ Returns the number of \f[I]significant decimal digits\f[R] in
|
|||
.PP
|
||||
All procedures in this section require a valid current context.
|
||||
.PP
|
||||
All procedures in this section consume the given \f[B]BclNumber\f[R]
|
||||
arguments that are not given to pointer arguments.
|
||||
All procedures in this section without the \f[B]_keep\f[R] suffix in
|
||||
their name consume the given \f[B]BclNumber\f[R] arguments that are not
|
||||
given to pointer arguments.
|
||||
See the \f[B]Consumption and Propagation\f[R] subsection below.
|
||||
.TP
|
||||
\f[B]BclNumber bcl_parse(const char *restrict\f[R] \f[I]val\f[R]\f[B])\f[R]
|
||||
|
@ -644,6 +691,11 @@ The string is dynamically allocated and must be freed by the caller.
|
|||
See the \f[B]Consumption and Propagation\f[R] subsection below.
|
||||
.RE
|
||||
.TP
|
||||
\f[B]char* bcl_string_keep(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R]
|
||||
Returns a string representation of \f[I]n\f[R] according the the current
|
||||
context\[cq]s \f[B]ibase\f[R].
|
||||
The string is dynamically allocated and must be freed by the caller.
|
||||
.TP
|
||||
\f[B]BclError bcl_bigdig(BclNumber\f[R] \f[I]n\f[R]\f[B], BclBigDig *\f[R]\f[I]result\f[R]\f[B])\f[R]
|
||||
Converts \f[I]n\f[R] into a \f[B]BclBigDig\f[R] and returns the result
|
||||
in the space pointed to by \f[I]result\f[R].
|
||||
|
@ -665,6 +717,24 @@ Otherwise, this function can return:
|
|||
See the \f[B]Consumption and Propagation\f[R] subsection below.
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclError bcl_bigdig_keep(BclNumber\f[R] \f[I]n\f[R]\f[B], BclBigDig *\f[R]\f[I]result\f[R]\f[B])\f[R]
|
||||
Converts \f[I]n\f[R] into a \f[B]BclBigDig\f[R] and returns the result
|
||||
in the space pointed to by \f[I]result\f[R].
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] must be smaller than \f[B]BC_OVERFLOW_MAX\f[R].
|
||||
See the \f[B]LIMITS\f[R] section.
|
||||
.PP
|
||||
If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned.
|
||||
Otherwise, this function can return:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_OVERFLOW\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]\f[B])\f[R]
|
||||
Creates a \f[B]BclNumber\f[R] from \f[I]val\f[R].
|
||||
.RS
|
||||
|
@ -681,6 +751,11 @@ Possible errors include:
|
|||
.PP
|
||||
All procedures in this section require a valid current context.
|
||||
.PP
|
||||
All procedures in this section without the \f[B]_keep\f[R] suffix in
|
||||
their name consume the given \f[B]BclNumber\f[R] arguments that are not
|
||||
given to pointer arguments.
|
||||
See the \f[B]Consumption and Propagation\f[R] subsection below.
|
||||
.PP
|
||||
All procedures in this section can return the following errors:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
|
@ -712,6 +787,25 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_add_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Adds \f[I]a\f[R] and \f[I]b\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is the max of the \f[I]scale\f[R]s of
|
||||
\f[I]a\f[R] and \f[I]b\f[R].
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_sub(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Subtracts \f[I]b\f[R] from \f[I]a\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is the max of the \f[I]scale\f[R]s of
|
||||
|
@ -735,6 +829,25 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_sub_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Subtracts \f[I]b\f[R] from \f[I]a\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is the max of the \f[I]scale\f[R]s of
|
||||
\f[I]a\f[R] and \f[I]b\f[R].
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_mul(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Multiplies \f[I]a\f[R] and \f[I]b\f[R] and returns the result.
|
||||
If \f[I]ascale\f[R] is the \f[I]scale\f[R] of \f[I]a\f[R] and
|
||||
|
@ -761,6 +874,28 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_mul_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Multiplies \f[I]a\f[R] and \f[I]b\f[R] and returns the result.
|
||||
If \f[I]ascale\f[R] is the \f[I]scale\f[R] of \f[I]a\f[R] and
|
||||
\f[I]bscale\f[R] is the \f[I]scale\f[R] of \f[I]b\f[R], the
|
||||
\f[I]scale\f[R] of the result is equal to
|
||||
\f[B]min(ascale+bscale,max(scale,ascale,bscale))\f[R], where
|
||||
\f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_div(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is the \f[I]scale\f[R] of the current
|
||||
|
@ -788,6 +923,29 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_div_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is the \f[I]scale\f[R] of the current
|
||||
context.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]b\f[R] cannot be \f[B]0\f[R].
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_mod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Divides \f[I]a\f[R] by \f[I]b\f[R] to the \f[I]scale\f[R] of the current
|
||||
context, computes the modulus \f[B]a-(a/b)*b\f[R], and returns the
|
||||
|
@ -815,6 +973,29 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_mod_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Divides \f[I]a\f[R] by \f[I]b\f[R] to the \f[I]scale\f[R] of the current
|
||||
context, computes the modulus \f[B]a-(a/b)*b\f[R], and returns the
|
||||
modulus.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]b\f[R] cannot be \f[B]0\f[R].
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_pow(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Calculates \f[I]a\f[R] to the power of \f[I]b\f[R] to the
|
||||
\f[I]scale\f[R] of the current context.
|
||||
|
@ -851,6 +1032,38 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_pow_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Calculates \f[I]a\f[R] to the power of \f[I]b\f[R] to the
|
||||
\f[I]scale\f[R] of the current context.
|
||||
\f[I]b\f[R] must be an integer, but can be negative.
|
||||
If it is negative, \f[I]a\f[R] must be non-zero.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]b\f[R] must be an integer.
|
||||
If \f[I]b\f[R] is negative, \f[I]a\f[R] must not be \f[B]0\f[R].
|
||||
.PP
|
||||
\f[I]a\f[R] must be smaller than \f[B]BC_OVERFLOW_MAX\f[R].
|
||||
See the \f[B]LIMITS\f[R] section.
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_OVERFLOW\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_lshift(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Shifts \f[I]a\f[R] left (moves the radix right) by \f[I]b\f[R] places
|
||||
and returns the result.
|
||||
|
@ -879,6 +1092,30 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_lshift_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Shifts \f[I]a\f[R] left (moves the radix right) by \f[I]b\f[R] places
|
||||
and returns the result.
|
||||
This is done in decimal.
|
||||
\f[I]b\f[R] must be an integer.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]b\f[R] must be an integer.
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_rshift(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Shifts \f[I]a\f[R] right (moves the radix left) by \f[I]b\f[R] places
|
||||
and returns the result.
|
||||
|
@ -907,6 +1144,30 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_rshift_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R]
|
||||
Shifts \f[I]a\f[R] right (moves the radix left) by \f[I]b\f[R] places
|
||||
and returns the result.
|
||||
This is done in decimal.
|
||||
\f[I]b\f[R] must be an integer.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]b\f[R] must be an integer.
|
||||
.PP
|
||||
\f[I]a\f[R] and \f[I]b\f[R] can be the same number.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]\f[B])\f[R]
|
||||
Calculates the square root of \f[I]a\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is equal to the \f[B]scale\f[R] of the
|
||||
|
@ -931,6 +1192,27 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_sqrt_keep(BclNumber\f[R] \f[I]a\f[R]\f[B])\f[R]
|
||||
Calculates the square root of \f[I]a\f[R] and returns the result.
|
||||
The \f[I]scale\f[R] of the result is equal to the \f[B]scale\f[R] of the
|
||||
current context.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] cannot be negative.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NEGATIVE\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclError bcl_divmod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber *\f[R]\f[I]c\f[R]\f[B], BclNumber *\f[R]\f[I]d\f[R]\f[B])\f[R]
|
||||
Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the quotient in a new
|
||||
number which is put into the space pointed to by \f[I]c\f[R], and puts
|
||||
|
@ -959,6 +1241,30 @@ Otherwise, this function can return:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclError bcl_divmod_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber *\f[R]\f[I]c\f[R]\f[B], BclNumber *\f[R]\f[I]d\f[R]\f[B])\f[R]
|
||||
Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the quotient in a new
|
||||
number which is put into the space pointed to by \f[I]c\f[R], and puts
|
||||
the modulus in a new number which is put into the space pointed to by
|
||||
\f[I]d\f[R].
|
||||
.RS
|
||||
.PP
|
||||
\f[I]b\f[R] cannot be \f[B]0\f[R].
|
||||
.PP
|
||||
\f[I]c\f[R] and \f[I]d\f[R] cannot point to the same place, nor can they
|
||||
point to the space occupied by \f[I]a\f[R] or \f[I]b\f[R].
|
||||
.PP
|
||||
If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned.
|
||||
Otherwise, this function can return:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_modexp(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber\f[R] \f[I]c\f[R]\f[B])\f[R]
|
||||
Computes a modular exponentiation where \f[I]a\f[R] is the base,
|
||||
\f[I]b\f[R] is the exponent, and \f[I]c\f[R] is the modulus, and returns
|
||||
|
@ -991,6 +1297,35 @@ Possible errors include:
|
|||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_modexp_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber\f[R] \f[I]c\f[R]\f[B])\f[R]
|
||||
Computes a modular exponentiation where \f[I]a\f[R] is the base,
|
||||
\f[I]b\f[R] is the exponent, and \f[I]c\f[R] is the modulus, and returns
|
||||
the result.
|
||||
The \f[I]scale\f[R] of the result is equal to the \f[B]scale\f[R] of the
|
||||
current context.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R], \f[I]b\f[R], and \f[I]c\f[R] must be integers.
|
||||
\f[I]c\f[R] must not be \f[B]0\f[R].
|
||||
\f[I]b\f[R] must not be negative.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NEGATIVE\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.SS Miscellaneous
|
||||
.TP
|
||||
\f[B]void bcl_zero(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R]
|
||||
|
@ -1060,6 +1395,11 @@ char[\f[R]\f[I]BCL_SEED_SIZE\f[R]\f[B]])\f[R]
|
|||
.IP \[bu] 2
|
||||
\f[B]bcl_rand_reseed(\f[R]\f[I]void\f[R]\f[B])\f[R]
|
||||
.PP
|
||||
All procedures in this section without the \f[B]_keep\f[R] suffix in
|
||||
their name consume the given \f[B]BclNumber\f[R] arguments that are not
|
||||
given to pointer arguments.
|
||||
See the \f[B]Consumption and Propagation\f[R] subsection below.
|
||||
.PP
|
||||
The following items allow clients to use the pseudo-random number
|
||||
generator.
|
||||
All procedures require a valid current context.
|
||||
|
@ -1112,6 +1452,36 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_irand_keep(BclNumber\f[R] \f[I]a\f[R]\f[B])\f[R]
|
||||
Returns a random number that is not larger than \f[I]a\f[R] in a new
|
||||
number.
|
||||
If \f[I]a\f[R] is \f[B]0\f[R] or \f[B]1\f[R], the new number is equal to
|
||||
\f[B]0\f[R].
|
||||
The bound is unlimited, so it is not bound to the size of
|
||||
\f[B]BclRandInt\f[R].
|
||||
This is done by generating as many random numbers as necessary,
|
||||
multiplying them by certain exponents, and adding them all together.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] must be an integer and non-negative.
|
||||
.PP
|
||||
This procedure requires a valid current context.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NEGATIVE\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]\f[B])\f[R]
|
||||
Returns a random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R]
|
||||
(exclusive) that has \f[I]places\f[R] decimal digits after the radix
|
||||
|
@ -1158,11 +1528,55 @@ Possible errors include:
|
|||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclNumber bcl_ifrand_keep(BclNumber\f[R] \f[I]a\f[R]\f[B], size_t\f[R] \f[I]places\f[R]\f[B])\f[R]
|
||||
Returns a random number less than \f[I]a\f[R] with \f[I]places\f[R]
|
||||
decimal digits after the radix (decimal point).
|
||||
There are no limits on \f[I]a\f[R] or \f[I]places\f[R].
|
||||
.RS
|
||||
.PP
|
||||
\f[I]a\f[R] must be an integer and non-negative.
|
||||
.PP
|
||||
This procedure requires a valid current context.
|
||||
.PP
|
||||
bcl(3) will encode an error in the return value, if there was one.
|
||||
The error can be queried with \f[B]bcl_err(BclNumber)\f[R].
|
||||
Possible errors include:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NEGATIVE\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R]
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R]
|
||||
Seeds the PRNG with \f[I]n\f[R].
|
||||
.RS
|
||||
.PP
|
||||
\f[I]n\f[R] is \f[I]not\f[R] consumed.
|
||||
\f[I]n\f[R] is consumed.
|
||||
.PP
|
||||
This procedure requires a valid current context.
|
||||
.PP
|
||||
If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned.
|
||||
Otherwise, this function can return:
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_NUM\f[R]
|
||||
.IP \[bu] 2
|
||||
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
|
||||
.PP
|
||||
Note that if \f[B]bcl_rand_seed2num(\f[R]\f[I]void\f[R]\f[B])\f[R] or
|
||||
\f[B]bcl_rand_seed2num_err(BclNumber)\f[R] are called right after this
|
||||
function, they are not guaranteed to return a number equal to
|
||||
\f[I]n\f[R].
|
||||
.RE
|
||||
.TP
|
||||
\f[B]BclError bcl_rand_seedWithNum_keep(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R]
|
||||
Seeds the PRNG with \f[I]n\f[R].
|
||||
.RS
|
||||
.PP
|
||||
This procedure requires a valid current context.
|
||||
.PP
|
||||
|
@ -1253,7 +1667,7 @@ so the example above should properly be:
|
|||
.nf
|
||||
\f[C]
|
||||
BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
|
||||
if (bc_num_err(n) != BCL_ERROR_NONE) {
|
||||
if (bcl_err(n) != BCL_ERROR_NONE) {
|
||||
// Handle the error.
|
||||
}
|
||||
\f[R]
|
||||
|
|
|
@ -136,8 +136,12 @@ These items allow clients to convert numbers into and from strings and integers.
|
|||
|
||||
**char\* bcl_string(BclNumber** _n_**);**
|
||||
|
||||
**char\* bcl_string_keep(BclNumber** _n_**);**
|
||||
|
||||
**BclError bcl_bigdig(BclNumber** _n_**, BclBigDig \***_result_**);**
|
||||
|
||||
**BclError bcl_bigdig_keep(BclNumber** _n_**, BclBigDig \***_result_**);**
|
||||
|
||||
**BclNumber bcl_bigdig2num(BclBigDig** _val_**);**
|
||||
|
||||
## Math
|
||||
|
@ -146,26 +150,48 @@ These items allow clients to run math on numbers.
|
|||
|
||||
**BclNumber bcl_add(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_add_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_sub(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_sub_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_mul(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_mul_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_div(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_div_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_mod(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_mod_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_pow(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_pow_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_lshift(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_lshift_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_rshift(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_rshift_keep(BclNumber** _a_**, BclNumber** _b_**);**
|
||||
|
||||
**BclNumber bcl_sqrt(BclNumber** _a_**);**
|
||||
|
||||
**BclNumber bcl_sqrt_keep(BclNumber** _a_**);**
|
||||
|
||||
**BclError bcl_divmod(BclNumber** _a_**, BclNumber** _b_**, BclNumber \***_c_**, BclNumber \***_d_**);**
|
||||
|
||||
**BclError bcl_divmod_keep(BclNumber** _a_**, BclNumber** _b_**, BclNumber \***_c_**, BclNumber \***_d_**);**
|
||||
|
||||
**BclNumber bcl_modexp(BclNumber** _a_**, BclNumber** _b_**, BclNumber** _c_**);**
|
||||
|
||||
**BclNumber bcl_modexp_keep(BclNumber** _a_**, BclNumber** _b_**, BclNumber** _c_**);**
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
These items are miscellaneous.
|
||||
|
@ -195,12 +221,18 @@ generator in bcl(3).
|
|||
|
||||
**BclNumber bcl_irand(BclNumber** _a_**);**
|
||||
|
||||
**BclNumber bcl_irand_keep(BclNumber** _a_**);**
|
||||
|
||||
**BclNumber bcl_frand(size_t** _places_**);**
|
||||
|
||||
**BclNumber bcl_ifrand(BclNumber** _a_**, size_t** _places_**);**
|
||||
|
||||
**BclNumber bcl_ifrand_keep(BclNumber** _a_**, size_t** _places_**);**
|
||||
|
||||
**BclError bcl_rand_seedWithNum(BclNumber** _n_**);**
|
||||
|
||||
**BclError bcl_rand_seedWithNum_keep(BclNumber** _n_**);**
|
||||
|
||||
**BclError bcl_rand_seed(unsigned char** _seed_**[**_BCL_SEED_SIZE_**]);**
|
||||
|
||||
**void bcl_rand_reseed(**_void_**);**
|
||||
|
@ -548,9 +580,9 @@ All procedures in this section require a valid current context.
|
|||
|
||||
All procedures in this section require a valid current context.
|
||||
|
||||
All procedures in this section consume the given **BclNumber** arguments that
|
||||
are not given to pointer arguments. See the **Consumption and Propagation**
|
||||
subsection below.
|
||||
All procedures in this section without the **_keep** suffix in their name
|
||||
consume the given **BclNumber** arguments that are not given to pointer
|
||||
arguments. See the **Consumption and Propagation** subsection below.
|
||||
|
||||
**BclNumber bcl_parse(const char \*restrict** _val_**)**
|
||||
|
||||
|
@ -578,6 +610,12 @@ subsection below.
|
|||
*n* is consumed; it cannot be used after the call. See the
|
||||
**Consumption and Propagation** subsection below.
|
||||
|
||||
**char\* bcl_string_keep(BclNumber** _n_**)**
|
||||
|
||||
: Returns a string representation of *n* according the the current context's
|
||||
**ibase**. The string is dynamically allocated and must be freed by the
|
||||
caller.
|
||||
|
||||
**BclError bcl_bigdig(BclNumber** _n_**, BclBigDig \***_result_**)**
|
||||
|
||||
: Converts *n* into a **BclBigDig** and returns the result in the space
|
||||
|
@ -595,6 +633,20 @@ subsection below.
|
|||
*n* is consumed; it cannot be used after the call. See the
|
||||
**Consumption and Propagation** subsection below.
|
||||
|
||||
**BclError bcl_bigdig_keep(BclNumber** _n_**, BclBigDig \***_result_**)**
|
||||
|
||||
: Converts *n* into a **BclBigDig** and returns the result in the space
|
||||
pointed to by *result*.
|
||||
|
||||
*a* must be smaller than **BC_OVERFLOW_MAX**. See the **LIMITS** section.
|
||||
|
||||
If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this
|
||||
function can return:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_OVERFLOW**
|
||||
|
||||
**BclNumber bcl_bigdig2num(BclBigDig** _val_**)**
|
||||
|
||||
: Creates a **BclNumber** from *val*.
|
||||
|
@ -609,6 +661,10 @@ subsection below.
|
|||
|
||||
All procedures in this section require a valid current context.
|
||||
|
||||
All procedures in this section without the **_keep** suffix in their name
|
||||
consume the given **BclNumber** arguments that are not given to pointer
|
||||
arguments. See the **Consumption and Propagation** subsection below.
|
||||
|
||||
All procedures in this section can return the following errors:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
|
@ -632,6 +688,20 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_add_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Adds *a* and *b* and returns the result. The *scale* of the result is the
|
||||
max of the *scale*s of *a* and *b*.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_sub(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Subtracts *b* from *a* and returns the result. The *scale* of the result is
|
||||
|
@ -649,6 +719,20 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_sub_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Subtracts *b* from *a* and returns the result. The *scale* of the result is
|
||||
the max of the *scale*s of *a* and *b*.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_mul(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Multiplies *a* and *b* and returns the result. If *ascale* is the *scale* of
|
||||
|
@ -668,6 +752,22 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_mul_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Multiplies *a* and *b* and returns the result. If *ascale* is the *scale* of
|
||||
*a* and *bscale* is the *scale* of *b*, the *scale* of the result is equal
|
||||
to **min(ascale+bscale,max(scale,ascale,bscale))**, where **min()** and
|
||||
**max()** return the obvious values.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_div(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Divides *a* by *b* and returns the result. The *scale* of the result is the
|
||||
|
@ -688,6 +788,23 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_div_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Divides *a* by *b* and returns the result. The *scale* of the result is the
|
||||
*scale* of the current context.
|
||||
|
||||
*b* cannot be **0**.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_mod(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Divides *a* by *b* to the *scale* of the current context, computes the
|
||||
|
@ -708,6 +825,23 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_mod_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Divides *a* by *b* to the *scale* of the current context, computes the
|
||||
modulus **a-(a/b)\*b**, and returns the modulus.
|
||||
|
||||
*b* cannot be **0**.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_pow(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Calculates *a* to the power of *b* to the *scale* of the current context.
|
||||
|
@ -733,6 +867,28 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_pow_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Calculates *a* to the power of *b* to the *scale* of the current context.
|
||||
*b* must be an integer, but can be negative. If it is negative, *a* must
|
||||
be non-zero.
|
||||
|
||||
*b* must be an integer. If *b* is negative, *a* must not be **0**.
|
||||
|
||||
*a* must be smaller than **BC_OVERFLOW_MAX**. See the **LIMITS** section.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_MATH_OVERFLOW**
|
||||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_lshift(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Shifts *a* left (moves the radix right) by *b* places and returns the
|
||||
|
@ -753,6 +909,23 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_lshift_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Shifts *a* left (moves the radix right) by *b* places and returns the
|
||||
result. This is done in decimal. *b* must be an integer.
|
||||
|
||||
*b* must be an integer.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_rshift(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Shifts *a* right (moves the radix left) by *b* places and returns the
|
||||
|
@ -773,6 +946,23 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_rshift_keep(BclNumber** _a_**, BclNumber** _b_**)**
|
||||
|
||||
: Shifts *a* right (moves the radix left) by *b* places and returns the
|
||||
result. This is done in decimal. *b* must be an integer.
|
||||
|
||||
*b* must be an integer.
|
||||
|
||||
*a* and *b* can be the same number.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_sqrt(BclNumber** _a_**)**
|
||||
|
||||
: Calculates the square root of *a* and returns the result. The *scale* of the
|
||||
|
@ -791,6 +981,21 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_NEGATIVE**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_sqrt_keep(BclNumber** _a_**)**
|
||||
|
||||
: Calculates the square root of *a* and returns the result. The *scale* of the
|
||||
result is equal to the **scale** of the current context.
|
||||
|
||||
*a* cannot be negative.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NEGATIVE**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclError bcl_divmod(BclNumber** _a_**, BclNumber** _b_**, BclNumber \***_c_**, BclNumber \***_d_**)**
|
||||
|
||||
: Divides *a* by *b* and returns the quotient in a new number which is put
|
||||
|
@ -813,6 +1018,25 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclError bcl_divmod_keep(BclNumber** _a_**, BclNumber** _b_**, BclNumber \***_c_**, BclNumber \***_d_**)**
|
||||
|
||||
: Divides *a* by *b* and returns the quotient in a new number which is put
|
||||
into the space pointed to by *c*, and puts the modulus in a new number which
|
||||
is put into the space pointed to by *d*.
|
||||
|
||||
*b* cannot be **0**.
|
||||
|
||||
*c* and *d* cannot point to the same place, nor can they point to the space
|
||||
occupied by *a* or *b*.
|
||||
|
||||
If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this
|
||||
function can return:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_modexp(BclNumber** _a_**, BclNumber** _b_**, BclNumber** _c_**)**
|
||||
|
||||
: Computes a modular exponentiation where *a* is the base, *b* is the
|
||||
|
@ -835,6 +1059,25 @@ All procedures in this section can return the following errors:
|
|||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_modexp_keep(BclNumber** _a_**, BclNumber** _b_**, BclNumber** _c_**)**
|
||||
|
||||
: Computes a modular exponentiation where *a* is the base, *b* is the
|
||||
exponent, and *c* is the modulus, and returns the result. The *scale* of the
|
||||
result is equal to the **scale** of the current context.
|
||||
|
||||
*a*, *b*, and *c* must be integers. *c* must not be **0**. *b* must not be
|
||||
negative.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NEGATIVE**
|
||||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_MATH_DIVIDE_BY_ZERO**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
**void bcl_zero(BclNumber** _n_**)**
|
||||
|
@ -891,6 +1134,10 @@ If necessary, the PRNG can be reseeded with one of the following functions:
|
|||
* **bcl_rand_seed(unsigned char[**_BCL_SEED_SIZE_**])**
|
||||
* **bcl_rand_reseed(**_void_**)**
|
||||
|
||||
All procedures in this section without the **_keep** suffix in their name
|
||||
consume the given **BclNumber** arguments that are not given to pointer
|
||||
arguments. See the **Consumption and Propagation** subsection below.
|
||||
|
||||
The following items allow clients to use the pseudo-random number generator. All
|
||||
procedures require a valid current context.
|
||||
|
||||
|
@ -921,8 +1168,29 @@ procedures require a valid current context.
|
|||
|
||||
*a* must be an integer and non-negative.
|
||||
|
||||
*a* is consumed; it cannot be used after the call. See the
|
||||
**Consumption and Propagation** subsection below.
|
||||
*a* is consumed; it cannot be used after the call. See the **Consumption and
|
||||
Propagation** subsection below.
|
||||
|
||||
This procedure requires a valid current context.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NEGATIVE**
|
||||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_irand_keep(BclNumber** _a_**)**
|
||||
|
||||
: Returns a random number that is not larger than *a* in a new number. If *a*
|
||||
is **0** or **1**, the new number is equal to **0**. The bound is unlimited,
|
||||
so it is not bound to the size of **BclRandInt**. This is done by generating
|
||||
as many random numbers as necessary, multiplying them by certain exponents,
|
||||
and adding them all together.
|
||||
|
||||
*a* must be an integer and non-negative.
|
||||
|
||||
This procedure requires a valid current context.
|
||||
|
||||
|
@ -956,8 +1224,26 @@ procedures require a valid current context.
|
|||
|
||||
*a* must be an integer and non-negative.
|
||||
|
||||
*a* is consumed; it cannot be used after the call. See the
|
||||
**Consumption and Propagation** subsection below.
|
||||
*a* is consumed; it cannot be used after the call. See the **Consumption and
|
||||
Propagation** subsection below.
|
||||
|
||||
This procedure requires a valid current context.
|
||||
|
||||
bcl(3) will encode an error in the return value, if there was one. The error
|
||||
can be queried with **bcl_err(BclNumber)**. Possible errors include:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
* **BCL_ERROR_MATH_NEGATIVE**
|
||||
* **BCL_ERROR_MATH_NON_INTEGER**
|
||||
* **BCL_ERROR_FATAL_ALLOC_ERR**
|
||||
|
||||
**BclNumber bcl_ifrand_keep(BclNumber** _a_**, size_t** _places_**)**
|
||||
|
||||
: Returns a random number less than *a* with *places* decimal digits after the
|
||||
radix (decimal point). There are no limits on *a* or *places*.
|
||||
|
||||
*a* must be an integer and non-negative.
|
||||
|
||||
This procedure requires a valid current context.
|
||||
|
||||
|
@ -974,7 +1260,23 @@ procedures require a valid current context.
|
|||
|
||||
: Seeds the PRNG with *n*.
|
||||
|
||||
*n* is *not* consumed.
|
||||
*n* is consumed.
|
||||
|
||||
This procedure requires a valid current context.
|
||||
|
||||
If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this
|
||||
function can return:
|
||||
|
||||
* **BCL_ERROR_INVALID_NUM**
|
||||
* **BCL_ERROR_INVALID_CONTEXT**
|
||||
|
||||
Note that if **bcl_rand_seed2num(**_void_**)** or
|
||||
**bcl_rand_seed2num_err(BclNumber)** are called right after this function,
|
||||
they are not guaranteed to return a number equal to *n*.
|
||||
|
||||
**BclError bcl_rand_seedWithNum_keep(BclNumber** _n_**)**
|
||||
|
||||
: Seeds the PRNG with *n*.
|
||||
|
||||
This procedure requires a valid current context.
|
||||
|
||||
|
@ -1046,7 +1348,7 @@ checked with **bcl_err(BclNumber)**, so the example above should properly
|
|||
be:
|
||||
|
||||
BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
|
||||
if (bc_num_err(n) != BCL_ERROR_NONE) {
|
||||
if (bcl_err(n) != BCL_ERROR_NONE) {
|
||||
// Handle the error.
|
||||
}
|
||||
|
||||
|
|
|
@ -1151,47 +1151,60 @@ const uchar dc_parse_insts[] = {
|
|||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_TRUNC,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_POWER, BC_INST_MULTIPLY, BC_INST_DIVIDE,
|
||||
BC_INST_MODULUS, BC_INST_PLUS, BC_INST_MINUS,
|
||||
BC_INST_POWER, BC_INST_MULTIPLY,
|
||||
BC_INST_DIVIDE, BC_INST_MODULUS,
|
||||
BC_INST_PLUS, BC_INST_MINUS,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_PLACES, BC_INST_LSHIFT, BC_INST_RSHIFT,
|
||||
BC_INST_PLACES, BC_INST_LSHIFT,
|
||||
BC_INST_RSHIFT,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_BOOL_OR, BC_INST_BOOL_AND,
|
||||
#if BC_ENABLED
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
#endif // BC_ENABLED
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_REL_GT, BC_INST_REL_LT, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE,
|
||||
BC_INST_INVALID, BC_INST_REL_LE, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_REL_GT,
|
||||
BC_INST_REL_LT, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_REL_GE, BC_INST_INVALID,
|
||||
BC_INST_REL_LE, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
#if BC_ENABLED
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID,
|
||||
#endif // BC_ENABLED
|
||||
BC_INST_IBASE, BC_INST_OBASE, BC_INST_SCALE,
|
||||
BC_INST_IBASE, BC_INST_OBASE,
|
||||
BC_INST_SCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_SEED,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_LENGTH, BC_INST_PRINT, BC_INST_SQRT,
|
||||
BC_INST_ABS, BC_INST_IS_NUMBER, BC_INST_IS_STRING,
|
||||
BC_INST_LENGTH, BC_INST_PRINT,
|
||||
BC_INST_SQRT, BC_INST_ABS,
|
||||
BC_INST_IS_NUMBER, BC_INST_IS_STRING,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_IRAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_ASCIIFY, BC_INST_MODEXP, BC_INST_DIVMOD,
|
||||
BC_INST_QUIT, BC_INST_INVALID,
|
||||
BC_INST_ASCIIFY, BC_INST_MODEXP,
|
||||
BC_INST_DIVMOD, BC_INST_QUIT,
|
||||
BC_INST_INVALID,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_RAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_MAXIBASE, BC_INST_MAXOBASE, BC_INST_MAXSCALE,
|
||||
BC_INST_MAXIBASE, BC_INST_MAXOBASE,
|
||||
BC_INST_MAXSCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_MAXRAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
@ -1199,17 +1212,21 @@ const uchar dc_parse_insts[] = {
|
|||
#if BC_ENABLED
|
||||
BC_INST_INVALID,
|
||||
#endif // BC_ENABLED
|
||||
BC_INST_LEADING_ZERO, BC_INST_PRINT_STREAM, BC_INST_INVALID,
|
||||
BC_INST_EXTENDED_REGISTERS, BC_INST_REL_EQ, BC_INST_INVALID,
|
||||
BC_INST_EXECUTE, BC_INST_PRINT_STACK, BC_INST_CLEAR_STACK,
|
||||
BC_INST_INVALID, BC_INST_STACK_LEN, BC_INST_DUPLICATE,
|
||||
BC_INST_SWAP, BC_INST_POP, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_LEADING_ZERO, BC_INST_PRINT_STREAM,
|
||||
BC_INST_INVALID, BC_INST_EXTENDED_REGISTERS,
|
||||
BC_INST_REL_EQ, BC_INST_INVALID,
|
||||
BC_INST_EXECUTE, BC_INST_PRINT_STACK,
|
||||
BC_INST_CLEAR_STACK, BC_INST_INVALID,
|
||||
BC_INST_STACK_LEN, BC_INST_DUPLICATE,
|
||||
BC_INST_SWAP, BC_INST_POP,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_INVALID,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_PRINT_POP, BC_INST_NQUIT, BC_INST_EXEC_STACK_LEN,
|
||||
BC_INST_INVALID, BC_INST_INVALID,
|
||||
BC_INST_INVALID, BC_INST_PRINT_POP,
|
||||
BC_INST_NQUIT, BC_INST_EXEC_STACK_LEN,
|
||||
BC_INST_SCALE_FUNC, BC_INST_INVALID,
|
||||
};
|
||||
#endif // DC_ENABLED
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -757,9 +757,16 @@ bc_program_read(BcProgram* p)
|
|||
// struct.
|
||||
bc_vec_init(&vm->read_buf, sizeof(char), BC_DTOR_NONE);
|
||||
}
|
||||
// This needs to be updated because the parser could have been used
|
||||
// somewhere else
|
||||
else bc_parse_updateFunc(&vm->read_prs, BC_PROG_READ);
|
||||
else
|
||||
{
|
||||
// This needs to be updated because the parser could have been used
|
||||
// somewhere else.
|
||||
bc_parse_updateFunc(&vm->read_prs, BC_PROG_READ);
|
||||
|
||||
// The read buffer also needs to be emptied or else it will still
|
||||
// contain previous read expressions.
|
||||
bc_vec_empty(&vm->read_buf);
|
||||
}
|
||||
|
||||
BC_SETJMP_LOCKED(vm, exec_err);
|
||||
|
||||
|
|
|
@ -643,12 +643,14 @@ bc_vm_shutdown(void)
|
|||
if (vm->catalog != BC_VM_INVALID_CATALOG) catclose(vm->catalog);
|
||||
#endif // BC_ENABLE_NLS
|
||||
|
||||
#if !BC_ENABLE_LIBRARY
|
||||
#if BC_ENABLE_HISTORY
|
||||
// This must always run to ensure that the terminal is back to normal, i.e.,
|
||||
// has raw mode disabled. But we should only do it if we did not have a bad
|
||||
// terminal because history was not initialized if it is a bad terminal.
|
||||
if (BC_TTY && !vm->history.badTerm) bc_history_free(&vm->history);
|
||||
#endif // BC_ENABLE_HISTORY
|
||||
#endif // !BC_ENABLE_LIBRARY
|
||||
|
||||
#if BC_DEBUG
|
||||
#if !BC_ENABLE_LIBRARY
|
||||
|
|
|
@ -55,7 +55,7 @@ main(void)
|
|||
BclError e;
|
||||
BclContext ctxt;
|
||||
size_t scale;
|
||||
BclNumber n, n2, n3, n4, n5, n6;
|
||||
BclNumber n, n2, n3, n4, n5, n6, n7;
|
||||
char* res;
|
||||
BclBigDig b = 0;
|
||||
|
||||
|
@ -123,16 +123,42 @@ main(void)
|
|||
// parse numbers as negative.
|
||||
if (!bcl_num_neg(n4)) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
// Add them and check the result.
|
||||
n5 = bcl_add_keep(n3, n4);
|
||||
err(bcl_err(n5));
|
||||
res = bcl_string(n5);
|
||||
if (res == NULL) err(BCL_ERROR_FATAL_ALLOC_ERR);
|
||||
if (strcmp(res, "-25452.9108273")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
// We want to ensure all memory gets freed because we run this under
|
||||
// Valgrind.
|
||||
free(res);
|
||||
|
||||
// Add them and check the result.
|
||||
n3 = bcl_add(n3, n4);
|
||||
err(bcl_err(n3));
|
||||
res = bcl_string(bcl_dup(n3));
|
||||
res = bcl_string_keep(n3);
|
||||
if (res == NULL) err(BCL_ERROR_FATAL_ALLOC_ERR);
|
||||
if (strcmp(res, "-25452.9108273")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
// We want to ensure all memory gets freed because we run this under
|
||||
// Valgrind.
|
||||
free(res);
|
||||
|
||||
// Ensure that divmod, a special case, works.
|
||||
n4 = bcl_parse("8937458902.2890347");
|
||||
err(bcl_err(n4));
|
||||
e = bcl_divmod_keep(n4, n3, &n5, &n6);
|
||||
err(e);
|
||||
|
||||
res = bcl_string(n5);
|
||||
if (strcmp(res, "-351137.0060159482")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
free(res);
|
||||
|
||||
res = bcl_string(n6);
|
||||
if (strcmp(res, ".00000152374405414")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
free(res);
|
||||
|
||||
// Ensure that divmod, a special case, works.
|
||||
n4 = bcl_parse("8937458902.2890347");
|
||||
err(bcl_err(n4));
|
||||
|
@ -140,15 +166,11 @@ main(void)
|
|||
err(e);
|
||||
|
||||
res = bcl_string(n5);
|
||||
|
||||
if (strcmp(res, "-351137.0060159482")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
free(res);
|
||||
|
||||
res = bcl_string(n6);
|
||||
|
||||
if (strcmp(res, ".00000152374405414")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
free(res);
|
||||
|
||||
// Ensure that sqrt works. This is also a special case. The reason is
|
||||
|
@ -213,10 +235,18 @@ main(void)
|
|||
n3 = bcl_irand(n4);
|
||||
err(bcl_err(n3));
|
||||
|
||||
// Repeat.
|
||||
n2 = bcl_ifrand_keep(n3, 10);
|
||||
err(bcl_err(n2));
|
||||
|
||||
// Repeat.
|
||||
n2 = bcl_ifrand(bcl_dup(n3), 10);
|
||||
err(bcl_err(n2));
|
||||
|
||||
// Still checking asserts.
|
||||
e = bcl_rand_seedWithNum_keep(n3);
|
||||
err(e);
|
||||
|
||||
// Still checking asserts.
|
||||
e = bcl_rand_seedWithNum(n3);
|
||||
err(e);
|
||||
|
@ -229,9 +259,12 @@ main(void)
|
|||
n5 = bcl_parse("10");
|
||||
err(bcl_err(n5));
|
||||
|
||||
n6 = bcl_modexp(bcl_dup(n5), bcl_dup(n5), bcl_dup(n5));
|
||||
n6 = bcl_modexp_keep(n5, n5, n5);
|
||||
err(bcl_err(n6));
|
||||
|
||||
n7 = bcl_modexp(bcl_dup(n5), bcl_dup(n5), bcl_dup(n5));
|
||||
err(bcl_err(n7));
|
||||
|
||||
// Clean up.
|
||||
bcl_num_free(n);
|
||||
|
||||
|
@ -250,6 +283,11 @@ main(void)
|
|||
n4 = bcl_parse("-1.01");
|
||||
err(bcl_err(n4));
|
||||
|
||||
res = bcl_string_keep(n);
|
||||
if (strcmp(res, ".01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
free(res);
|
||||
|
||||
res = bcl_string(bcl_dup(n));
|
||||
if (strcmp(res, ".01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ results="$testdir/$d/read_results.txt"
|
|||
errors="$testdir/$d/read_errors.txt"
|
||||
|
||||
out="$outputdir/${d}_outputs/read_results.txt"
|
||||
multiple_res="$outputdir/${d}_outputs/read_multiple_results.txt"
|
||||
outdir=$(dirname "$out")
|
||||
|
||||
# Make sure the directory exists.
|
||||
|
@ -89,11 +90,13 @@ if [ "$d" = "bc" ]; then
|
|||
halt="halt"
|
||||
read_call="read()"
|
||||
read_expr="${read_call}\n5+5;"
|
||||
read_multiple=$(printf '%s\n%s\n%s\n' "3" "2" "1")
|
||||
else
|
||||
options="-x"
|
||||
halt="q"
|
||||
read_call="?"
|
||||
read_expr="${read_call}"
|
||||
read_multiple=$(printf '%spR\n%spR\n%spR\n' "3" "2" "1")
|
||||
fi
|
||||
|
||||
# I use these, so unset them to make the tests work.
|
||||
|
@ -116,6 +119,16 @@ done < "$name"
|
|||
|
||||
printf 'pass\n'
|
||||
|
||||
printf 'Running %s read multiple...' "$d"
|
||||
|
||||
printf '3\n2\n1\n' > "$multiple_res"
|
||||
|
||||
# Run multiple read() calls.
|
||||
printf '%s\n' "$read_multiple" | "$exe" "$@" "$options" -e "$read_call" -e "$read_call" -e "$read_call" > "$out"
|
||||
checktest "$d" "$?" 'read multiple' "$multiple_res" "$out"
|
||||
|
||||
printf 'pass\n'
|
||||
|
||||
printf 'Running %s read errors...' "$d"
|
||||
|
||||
# Run read on every line.
|
||||
|
|
Loading…
Reference in a new issue