aboutsummaryrefslogtreecommitdiff
path: root/manuals/bcl.3
diff options
context:
space:
mode:
Diffstat (limited to 'manuals/bcl.3')
-rw-r--r--manuals/bcl.3666
1 files changed, 582 insertions, 84 deletions
diff --git a/manuals/bcl.3 b/manuals/bcl.3
index c079a20c..cb65a2b8 100644
--- a/manuals/bcl.3
+++ b/manuals/bcl.3
@@ -1,7 +1,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\" Copyright (c) 2018-2023 Gavin D. Howard and contributors.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions are met:
@@ -25,7 +25,9 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.TH "BCL" "3" "June 2021" "Gavin D. Howard" "Libraries Manual"
+.TH "BCL" "3" "February 2023" "Gavin D. Howard" "Libraries Manual"
+.nh
+.ad l
.SH NAME
.PP
bcl - library of arbitrary precision decimal arithmetic
@@ -34,19 +36,16 @@ bcl - library of arbitrary precision decimal arithmetic
.PP
\f[I]#include <bcl.h>\f[R]
.PP
-Link with \f[I]-lbcl\f[R].
-.SS Signals
-.PP
-This procedure will allow clients to use signals to interrupt
-computations running in bcl(3).
-.PP
-\f[B]void bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B]);\f[R]
-.PP
-\f[B]bool bcl_running(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+Link with \f[I]-lbcl\f[R], and on POSIX systems, \f[I]-lpthread\f[R] is
+also required.
.SS Setup
.PP
These items allow clients to set up bcl(3).
.PP
+\f[B]BclError bcl_start(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_end(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
\f[B]BclError bcl_init(\f[R]\f[I]void\f[R]\f[B]);\f[R]
.PP
\f[B]void bcl_free(\f[R]\f[I]void\f[R]\f[B]);\f[R]
@@ -55,7 +54,16 @@ These items allow clients to set up bcl(3).
.PP
\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]\f[B]);\f[R]
.PP
+\f[B]bool bcl_leadingZeroes(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_setLeadingZeroes(bool\f[R]
+\f[I]leadingZeroes\f[R]\f[B]);\f[R]
+.PP
\f[B]void bcl_gc(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]bool bcl_digitClamp(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_setDigitClamp(bool\f[R] \f[I]digitClamp\f[R]\f[B]);\f[R]
.SS Contexts
.PP
These items will allow clients to handle contexts, which are isolated
@@ -131,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
@@ -142,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.
@@ -201,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
@@ -223,67 +277,77 @@ generator in bcl(3).
.SH DESCRIPTION
.PP
bcl(3) is a library that implements arbitrary-precision decimal math, as
-standardized by
-POSIX (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
-in bc(1).
-.PP
-bcl(3) is async-signal-safe if
-\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] is used properly.
-(See the \f[B]SIGNAL HANDLING\f[R] section.)
+standardized by POSIX
+(https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) in
+bc(1).
.PP
-bcl(3) assumes that it is allowed to use the \f[B]bcl_\f[R] and
-\f[B]bc_\f[R] prefixes for symbol names without collision.
+bcl(3) assumes that it is allowed to use the \f[B]bcl\f[R],
+\f[B]Bcl\f[R], \f[B]bc\f[R], and \f[B]Bc\f[R] prefixes for symbol names
+without collision.
.PP
All of the items in its interface are described below.
See the documentation for each function for what each function can
return.
-.SS Signals
-.TP
-\f[B]void bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R]
-An async-signal-safe function that can be called from a signal handler.
-If called from a signal handler on the same thread as any executing
-bcl(3) functions, it will interrupt the functions and force them to
-return early.
-It is undefined behavior if this function is called from a thread that
-is \f[I]not\f[R] executing any bcl(3) functions while any bcl(3)
-functions are executing.
+.SS Setup
+.TP
+\f[B]BclError bcl_start(\f[R]\f[I]void\f[R]\f[B])\f[R]
+Initializes this library.
+This function can be called multiple times, but \f[B]bcl_end()\f[R] must
+only be called \f[I]once\f[R].
+This is to make it possible for multiple libraries and applications to
+initialize bcl(3) without problem.
.RS
.PP
-If execution \f[I]is\f[R] interrupted,
-\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] does \f[I]not\f[R]
-return to its caller.
+It is suggested that client libraries call this function, but do not
+call \f[B]bcl_end()\f[R], and client applications should call both.
.PP
-See the \f[B]SIGNAL HANDLING\f[R] section.
+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_FATAL_ALLOC_ERR\f[R]
+.PP
+This function must be the first one clients call.
+Calling any other function without calling this one first is undefined
+behavior.
.RE
.TP
-\f[B]bool bcl_running(\f[R]\f[I]void\f[R]\f[B])\f[R]
-An async-signal-safe function that can be called from a signal handler.
-It will return \f[B]true\f[R] if any bcl(3) procedures are running,
-which means it is safe to call
-\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R].
-Otherwise, it returns \f[B]false\f[R].
+\f[B]void bcl_end(\f[R]\f[I]void\f[R]\f[B])\f[R]
+Deinitializes this library.
+This function must only be called \f[I]once\f[R].
.RS
.PP
-See the \f[B]SIGNAL HANDLING\f[R] section.
+All data must have been freed before calling this function.
+.PP
+This function must be the last one clients call.
+Calling this function before calling any other function is undefined
+behavior.
.RE
-.SS Setup
.TP
\f[B]BclError bcl_init(\f[R]\f[I]void\f[R]\f[B])\f[R]
-Initializes this library.
+Initializes the library for the current thread.
This function can be called multiple times, but each call must be
matched by a call to \f[B]bcl_free(\f[R]\f[I]void\f[R]\f[B])\f[R].
This is to make it possible for multiple libraries and applications to
-initialize bcl(3) without problem.
+initialize threads for bcl(3) without problem.
.RS
.PP
+This function \f[I]must\f[R] be called from the thread that it is
+supposed to initialize.
+.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_FATAL_ALLOC_ERR\f[R]
.PP
-This function must be the first one clients call.
-Calling any other function without calling this one first is undefined
-behavior.
+This function must be the second one clients call.
+Calling any other function without calling \f[B]bcl_start()\f[R] and
+then this one first is undefined behavior, except in the case of new
+threads.
+New threads can safely call this function without calling
+\f[B]bcl_start()\f[R] if another thread has previously called
+\f[B]bcl_start()\f[R].
+But this function must still be the first function in bcl(3) called by
+that new thread.
.RE
.TP
\f[B]void bcl_free(\f[R]\f[I]void\f[R]\f[B])\f[R]
@@ -291,9 +355,12 @@ Decrements bcl(3)\[cq]s reference count and frees the data associated
with it if the reference count is \f[B]0\f[R].
.RS
.PP
-This function must be the last one clients call.
-Calling this function before calling any other function is undefined
-behavior.
+This function \f[I]must\f[R] be called from the thread that it is
+supposed to deinitialize.
+.PP
+This function must be the second to last one clients call.
+Calling this function before calling any other function besides
+\f[B]bcl_end()\f[R] is undefined behavior.
.RE
.TP
\f[B]bool bcl_abortOnFatalError(\f[R]\f[I]void\f[R]\f[B])\f[R]
@@ -304,6 +371,11 @@ a fatal error occurs.
.RS
.PP
If activated, clients do not need to check for fatal errors.
+.PP
+This value is \f[I]thread-local\f[R]; it applies to just the thread it
+is read on.
+.PP
+The default is \f[B]false\f[R].
.RE
.TP
\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]\f[B])\f[R]
@@ -314,9 +386,74 @@ If \f[I]abrt\f[R] is \f[B]true\f[R], bcl(3) will cause a
\f[B]SIGABRT\f[R] on fatal errors after the call.
.RS
.PP
+This value is \f[I]thread-local\f[R]; it applies to just the thread it
+is set on.
+.PP
If activated, clients do not need to check for fatal errors.
.RE
.TP
+\f[B]bool bcl_leadingZeroes(\f[R]\f[I]void\f[R]\f[B])\f[R]
+Queries and returns the state of whether leading zeroes are added to
+strings returned by \f[B]bcl_string()\f[R] when numbers are greater than
+\f[B]-1\f[R], less than \f[B]1\f[R], and not equal to \f[B]0\f[R].
+If \f[B]true\f[R] is returned, then leading zeroes will be added.
+.RS
+.PP
+This value is \f[I]thread-local\f[R]; it applies to just the thread it
+is read on.
+.PP
+The default is \f[B]false\f[R].
+.RE
+.TP
+\f[B]void bcl_setLeadingZeroes(bool\f[R] \f[I]leadingZeroes\f[R]\f[B])\f[R]
+Sets the state of whether leading zeroes are added to strings returned
+by \f[B]bcl_string()\f[R] when numbers are greater than \f[B]-1\f[R],
+less than \f[B]1\f[R], and not equal to \f[B]0\f[R].
+If \f[I]leadingZeroes\f[R] is \f[B]true\f[R], leading zeroes will be
+added to strings returned by \f[B]bcl_string()\f[R].
+.RS
+.PP
+This value is \f[I]thread-local\f[R]; it applies to just the thread it
+is set on.
+.RE
+.TP
+\f[B]bool bcl_digitClamp(\f[R]\f[I]void\f[R]\f[B])\f[R]
+Queries and returns the state of whether digits in number strings that
+are greater than or equal to the current \f[B]ibase\f[R] are clamped or
+not.
+.RS
+.PP
+If \f[B]true\f[R] is returned, then digits are treated as though they
+are equal to the value of \f[B]ibase\f[R] minus \f[B]1\f[R].
+If this is \f[I]not\f[R] true, then digits are treated as though they
+are equal to the value they would have if \f[B]ibase\f[R] was large
+enough.
+They are then multiplied by the appropriate power of \f[B]ibase\f[R].
+.PP
+For example, with clamping off and an \f[B]ibase\f[R] of \f[B]3\f[R],
+the string \[lq]AB\[rq] would equal \f[B]3\[ha]1*A+3\[ha]0*B\f[R], which
+is \f[B]3\f[R] times \f[B]10\f[R] plus \f[B]11\f[R], or \f[B]41\f[R],
+while with clamping on and an \f[B]ibase\f[R] of \f[B]3\f[R], the string
+\[lq]AB\[rq] would be equal to \f[B]3\[ha]1*2+3\[ha]0*2\f[R], which is
+\f[B]3\f[R] times \f[B]2\f[R] plus \f[B]2\f[R], or \f[B]8\f[R].
+.PP
+This value is \f[I]thread-local\f[R]; it applies to just the thread it
+is read on.
+.PP
+The default is \f[B]true\f[R].
+.RE
+.TP
+\f[B]void bcl_setDigitClamp(bool\f[R] \f[I]digitClamp\f[R]\f[B])\f[R]
+Sets the state of whether digits in number strings that are greater than
+or equal to the current \f[B]ibase\f[R] are clamped or not.
+For more information, see the
+\f[B]bcl_digitClamp(\f[R]\f[I]void\f[R]\f[B])\f[R] function.
+.RS
+.PP
+This value is \f[I]thread-local\f[R]; it applies to just the thread it
+is set on.
+.RE
+.TP
\f[B]void bcl_gc(\f[R]\f[I]void\f[R]\f[B])\f[R]
Garbage collects cached instances of arbitrary-precision numbers.
This only frees the memory of numbers that are \f[I]not\f[R] in use, so
@@ -365,6 +502,15 @@ Numbers created in one context are not valid in another context.
It is undefined behavior to use a number created in a different context.
Contexts are meant to isolate the numbers used by different clients in
the same application.
+.PP
+Different threads also have different contexts, so any numbers created
+in one thread are not valid in another thread.
+To pass values between contexts and threads, use \f[B]bcl_string()\f[R]
+to produce a string to pass around, and use \f[B]bcl_parse()\f[R] to
+parse the string.
+It is suggested that the \f[B]obase\f[R] used to create the string be
+passed around with the string and used as the \f[B]ibase\f[R] for
+\f[B]bcl_parse()\f[R] to ensure that the number will be the same.
.RE
.TP
\f[B]BclContext bcl_ctxt_create(\f[R]\f[I]void\f[R]\f[B])\f[R]
@@ -508,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]
@@ -544,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].
@@ -565,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
@@ -581,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]
@@ -612,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
@@ -635,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
@@ -661,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
@@ -688,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
@@ -715,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.
@@ -751,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.
@@ -779,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.
@@ -807,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
@@ -831,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
@@ -859,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
@@ -891,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]
@@ -960,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.
@@ -1012,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
@@ -1058,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
@@ -1153,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]
@@ -1173,9 +1687,6 @@ An invalid \f[B]BclNumber\f[R] was given as a parameter.
\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
An invalid \f[B]BclContext\f[R] is being used.
.TP
-\f[B]BCL_ERROR_SIGNAL\f[R]
-A signal interrupted execution.
-.TP
\f[B]BCL_ERROR_MATH_NEGATIVE\f[R]
A negative number was given as an argument to a parameter that cannot
accept negative numbers, such as for square roots.
@@ -1251,11 +1762,16 @@ this behavior.
.RE
.SH ATTRIBUTES
.PP
-When \f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] is used
-properly, bcl(3) is async-signal-safe.
+bcl(3) is \f[I]MT-Safe\f[R]: it is safe to call any functions from more
+than one thread.
+However, is is \f[I]not\f[R] safe to pass any data between threads
+except for strings returned by \f[B]bcl_string()\f[R].
.PP
-bcl(3) is \f[I]MT-Unsafe\f[R]: it is unsafe to call any functions from
-more than one thread.
+bcl(3) is not \f[I]async-signal-safe\f[R].
+It was not possible to make bcl(3) safe with signals and also make it
+safe with multiple threads.
+If it is necessary to be able to interrupt bcl(3), spawn a separate
+thread to run the calculation.
.SH PERFORMANCE
.PP
Most bc(1) implementations use \f[B]char\f[R] types to calculate the
@@ -1327,33 +1843,15 @@ These limits are meant to be effectively non-existent; the limits are so
large (at least on 64-bit machines) that there should not be any point
at which they become a problem.
In fact, memory should be exhausted before these limits should be hit.
-.SH SIGNAL HANDLING
-.PP
-If a signal handler calls
-\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] from the same
-thread that there are bcl(3) functions executing in, it will cause all
-execution to stop as soon as possible, interrupting long-running
-calculations, if necessary and cause the function that was executing to
-return.
-If possible, the error code \f[B]BC_ERROR_SIGNAL\f[R] is returned.
-.PP
-If execution \f[I]is\f[R] interrupted,
-\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] does \f[I]not\f[R]
-return to its caller.
-.PP
-It is undefined behavior if
-\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] is called from a
-thread that is not executing bcl(3) functions, if bcl(3) functions are
-executing.
.SH SEE ALSO
.PP
bc(1) and dc(1)
.SH STANDARDS
.PP
bcl(3) is compliant with the arithmetic defined in the IEEE Std
-1003.1-2017
-(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
-specification for bc(1).
+1003.1-2017 (\[lq]POSIX.1-2017\[rq]) specification at
+https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html for
+bc(1).
.PP
Note that the specification explicitly says that bc(1) only accepts
numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
@@ -1362,8 +1860,8 @@ This is also true of bcl(3).
.SH BUGS
.PP
None are known.
-Report bugs at https://git.yzena.com/gavin/bc.
+Report bugs at https://git.gavinhoward.com/gavin/bc.
.SH AUTHORS
.PP
Gavin D.
-Howard <gavin@yzena.com> and contributors.
+Howard <gavin@gavinhoward.com> and contributors.