You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2180 lines
68 KiB
2180 lines
68 KiB
.\" |
|
.\" SPDX-License-Identifier: BSD-2-Clause |
|
.\" |
|
.\" Copyright (c) 2018-2020 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: |
|
.\" |
|
.\" * Redistributions of source code must retain the above copyright notice, |
|
.\" this list of conditions and the following disclaimer. |
|
.\" |
|
.\" * Redistributions in binary form must reproduce the above copyright notice, |
|
.\" this list of conditions and the following disclaimer in the documentation |
|
.\" and/or other materials provided with the distribution. |
|
.\" |
|
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
.\" POSSIBILITY OF SUCH DAMAGE. |
|
.\" |
|
.TH "BC" "1" "July 2020" "Gavin D. Howard" "General Commands Manual" |
|
.SH NAME |
|
.PP |
|
bc \- arbitrary\-precision arithmetic language and calculator |
|
.SH SYNOPSIS |
|
.PP |
|
\f[B]bc\f[] [\f[B]\-ghilPqsvVw\f[]] [\f[B]\-\-global\-stacks\f[]] |
|
[\f[B]\-\-help\f[]] [\f[B]\-\-interactive\f[]] [\f[B]\-\-mathlib\f[]] |
|
[\f[B]\-\-no\-prompt\f[]] [\f[B]\-\-quiet\f[]] [\f[B]\-\-standard\f[]] |
|
[\f[B]\-\-warn\f[]] [\f[B]\-\-version\f[]] [\f[B]\-e\f[] \f[I]expr\f[]] |
|
[\f[B]\-\-expression\f[]=\f[I]expr\f[]...] [\f[B]\-f\f[] |
|
\f[I]file\f[]...] [\f[B]\-file\f[]=\f[I]file\f[]...] [\f[I]file\f[]...] |
|
.SH DESCRIPTION |
|
.PP |
|
bc(1) is an interactive processor for a language first standardized in |
|
1991 by POSIX. |
|
(The current standard is |
|
here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).) |
|
The language provides unlimited precision decimal arithmetic and is |
|
somewhat C\-like, but there are differences. |
|
Such differences will be noted in this document. |
|
.PP |
|
After parsing and handling options, this bc(1) reads any files given on |
|
the command line and executes them before reading from \f[B]stdin\f[]. |
|
.PP |
|
This bc(1) is a drop\-in replacement for \f[I]any\f[] bc(1), including |
|
(and especially) the GNU bc(1). |
|
It also has many extensions and extra features beyond other |
|
implementations. |
|
.SH OPTIONS |
|
.PP |
|
The following are the options that bc(1) accepts. |
|
.IP \[bu] 2 |
|
\f[B]\-g\f[], \f[B]\-\-global\-stacks\f[] |
|
.RS 2 |
|
.PP |
|
Turns the globals \f[B]ibase\f[], \f[B]obase\f[], \f[B]scale\f[], and |
|
\f[B]seed\f[] into stacks. |
|
.PP |
|
This has the effect that a copy of the current value of all four are |
|
pushed onto a stack for every function call, as well as popped when |
|
every function returns. |
|
This means that functions can assign to any and all of those globals |
|
without worrying that the change will affect other functions. |
|
Thus, a hypothetical function named \f[B]output(x,b)\f[] that simply |
|
printed \f[B]x\f[] in base \f[B]b\f[] could be written like this: |
|
.IP |
|
.nf |
|
\f[C] |
|
define\ void\ output(x,\ b)\ { |
|
\ \ \ \ obase=b |
|
\ \ \ \ x |
|
} |
|
\f[] |
|
.fi |
|
.PP |
|
instead of like this: |
|
.IP |
|
.nf |
|
\f[C] |
|
define\ void\ output(x,\ b)\ { |
|
\ \ \ \ auto\ c |
|
\ \ \ \ c=obase |
|
\ \ \ \ obase=b |
|
\ \ \ \ x |
|
\ \ \ \ obase=c |
|
} |
|
\f[] |
|
.fi |
|
.PP |
|
This makes writing functions much easier. |
|
.PP |
|
(\f[B]Note\f[]: the function \f[B]output(x,b)\f[] exists in the extended |
|
math library. |
|
See the \f[B]LIBRARY\f[] section.) |
|
.PP |
|
However, since using this flag means that functions cannot set |
|
\f[B]ibase\f[], \f[B]obase\f[], \f[B]scale\f[], or \f[B]seed\f[] |
|
globally, functions that are made to do so cannot work anymore. |
|
There are two possible use cases for that, and each has a solution. |
|
.PP |
|
First, if a function is called on startup to turn bc(1) into a number |
|
converter, it is possible to replace that capability with various shell |
|
aliases. |
|
Examples: |
|
.IP |
|
.nf |
|
\f[C] |
|
alias\ d2o="bc\ \-e\ ibase=A\ \-e\ obase=8" |
|
alias\ h2b="bc\ \-e\ ibase=G\ \-e\ obase=2" |
|
\f[] |
|
.fi |
|
.PP |
|
Second, if the purpose of a function is to set \f[B]ibase\f[], |
|
\f[B]obase\f[], \f[B]scale\f[], or \f[B]seed\f[] globally for any other |
|
purpose, it could be split into one to four functions (based on how many |
|
globals it sets) and each of those functions could return the desired |
|
value for a global. |
|
.PP |
|
For functions that set \f[B]seed\f[], the value assigned to |
|
\f[B]seed\f[] is not propagated to parent functions. |
|
This means that the sequence of pseudo\-random numbers that they see |
|
will not be the same sequence of pseudo\-random numbers that any parent |
|
sees. |
|
This is only the case once \f[B]seed\f[] has been set. |
|
.PP |
|
If a function desires to not affect the sequence of pseudo\-random |
|
numbers of its parents, but wants to use the same \f[B]seed\f[], it can |
|
use the following line: |
|
.IP |
|
.nf |
|
\f[C] |
|
seed\ =\ seed |
|
\f[] |
|
.fi |
|
.PP |
|
If the behavior of this option is desired for every run of bc(1), then |
|
users could make sure to define \f[B]BC_ENV_ARGS\f[] and include this |
|
option (see the \f[B]ENVIRONMENT VARIABLES\f[] section for more |
|
details). |
|
.PP |
|
If \f[B]\-s\f[], \f[B]\-w\f[], or any equivalents are used, this option |
|
is ignored. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-h\f[], \f[B]\-\-help\f[] |
|
.RS 2 |
|
.PP |
|
Prints a usage message and quits. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-i\f[], \f[B]\-\-interactive\f[] |
|
.RS 2 |
|
.PP |
|
Forces interactive mode. |
|
(See the \f[B]INTERACTIVE MODE\f[] section.) |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-l\f[], \f[B]\-\-mathlib\f[] |
|
.RS 2 |
|
.PP |
|
Sets \f[B]scale\f[] (see the \f[B]SYNTAX\f[] section) to \f[B]20\f[] and |
|
loads the included math library and the extended math library before |
|
running any code, including any expressions or files specified on the |
|
command line. |
|
.PP |
|
To learn what is in the libraries, see the \f[B]LIBRARY\f[] section. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-P\f[], \f[B]\-\-no\-prompt\f[] |
|
.RS 2 |
|
.PP |
|
Disables the prompt in TTY mode. |
|
(The prompt is only enabled in TTY mode. |
|
See the \f[B]TTY MODE\f[] section) This is mostly for those users that |
|
do not want a prompt or are not used to having them in bc(1). |
|
Most of those users would want to put this option in |
|
\f[B]BC_ENV_ARGS\f[] (see the \f[B]ENVIRONMENT VARIABLES\f[] section). |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-q\f[], \f[B]\-\-quiet\f[] |
|
.RS 2 |
|
.PP |
|
Do not print copyright header. |
|
bc(1) will also suppress the header in non\-interactive mode. |
|
.PP |
|
This is mostly for compatibility with the GNU |
|
bc(1) (https://www.gnu.org/software/bc/). |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-s\f[], \f[B]\-\-standard\f[] |
|
.RS 2 |
|
.PP |
|
Process exactly the language defined by the |
|
standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) |
|
and error if any extensions are used. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-v\f[], \f[B]\-V\f[], \f[B]\-\-version\f[] |
|
.RS 2 |
|
.PP |
|
Print the version information (copyright header) and exit. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-w\f[], \f[B]\-\-warn\f[] |
|
.RS 2 |
|
.PP |
|
Like \f[B]\-s\f[] and \f[B]\-\-standard\f[], except that warnings (and |
|
not errors) are printed for non\-standard extensions and execution |
|
continues normally. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-e\f[] \f[I]expr\f[], \f[B]\-\-expression\f[]=\f[I]expr\f[] |
|
.RS 2 |
|
.PP |
|
Evaluates \f[I]expr\f[]. |
|
If multiple expressions are given, they are evaluated in order. |
|
If files are given as well (see below), the expressions and files are |
|
evaluated in the order given. |
|
This means that if a file is given before an expression, the file is |
|
read in and evaluated first. |
|
.PP |
|
In other bc(1) implementations, this option causes the program to |
|
execute the expressions and then exit. |
|
This bc(1) does not, unless the \f[B]BC_EXPR_EXIT\f[] is defined (see |
|
the \f[B]ENVIRONMENT VARIABLES\f[] section). |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-f\f[] \f[I]file\f[], \f[B]\-\-file\f[]=\f[I]file\f[] |
|
.RS 2 |
|
.PP |
|
Reads in \f[I]file\f[] and evaluates it. |
|
If expressions are also given (see above), the expressions are evaluated |
|
in the order given. |
|
.PP |
|
In other bc(1) implementations, this option causes the program to |
|
execute the files and then exit. |
|
This bc(1) does not, unless the \f[B]BC_EXPR_EXIT\f[] is defined (see |
|
the \f[B]ENVIRONMENT VARIABLES\f[] section). |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.PP |
|
All long options are \f[B]non\-portable extensions\f[]. |
|
.SH STDOUT |
|
.PP |
|
Any non\-error output is written to \f[B]stdout\f[]. |
|
.PP |
|
\f[B]Note\f[]: Unlike other bc(1) implementations, this bc(1) will issue |
|
a fatal error (see the \f[B]EXIT STATUS\f[] section) if it cannot write |
|
to \f[B]stdout\f[], so if \f[B]stdout\f[] is closed, as in \f[B]bc |
|
>&\-\f[], it will quit with an error. |
|
This is done so that bc(1) can report problems when \f[B]stdout\f[] is |
|
redirected to a file. |
|
.PP |
|
If there are scripts that depend on the behavior of other bc(1) |
|
implementations, it is recommended that those scripts be changed to |
|
redirect \f[B]stdout\f[] to \f[B]/dev/null\f[]. |
|
.SH STDERR |
|
.PP |
|
Any error output is written to \f[B]stderr\f[]. |
|
.PP |
|
\f[B]Note\f[]: Unlike other bc(1) implementations, this bc(1) will issue |
|
a fatal error (see the \f[B]EXIT STATUS\f[] section) if it cannot write |
|
to \f[B]stderr\f[], so if \f[B]stderr\f[] is closed, as in \f[B]bc |
|
2>&\-\f[], it will quit with an error. |
|
This is done so that bc(1) can exit with an error code when |
|
\f[B]stderr\f[] is redirected to a file. |
|
.PP |
|
If there are scripts that depend on the behavior of other bc(1) |
|
implementations, it is recommended that those scripts be changed to |
|
redirect \f[B]stderr\f[] to \f[B]/dev/null\f[]. |
|
.SH SYNTAX |
|
.PP |
|
The syntax for bc(1) programs is mostly C\-like, with some differences. |
|
This bc(1) follows the POSIX |
|
standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html), |
|
which is a much more thorough resource for the language this bc(1) |
|
accepts. |
|
This section is meant to be a summary and a listing of all the |
|
extensions to the standard. |
|
.PP |
|
In the sections below, \f[B]E\f[] means expression, \f[B]S\f[] means |
|
statement, and \f[B]I\f[] means identifier. |
|
.PP |
|
Identifiers (\f[B]I\f[]) start with a lowercase letter and can be |
|
followed by any number (up to \f[B]BC_NAME_MAX\-1\f[]) of lowercase |
|
letters (\f[B]a\-z\f[]), digits (\f[B]0\-9\f[]), and underscores |
|
(\f[B]_\f[]). |
|
The regex is \f[B][a\-z][a\-z0\-9_]*\f[]. |
|
Identifiers with more than one character (letter) are a |
|
\f[B]non\-portable extension\f[]. |
|
.PP |
|
\f[B]ibase\f[] is a global variable determining how to interpret |
|
constant numbers. |
|
It is the "input" base, or the number base used for interpreting input |
|
numbers. |
|
\f[B]ibase\f[] is initially \f[B]10\f[]. |
|
If the \f[B]\-s\f[] (\f[B]\-\-standard\f[]) and \f[B]\-w\f[] |
|
(\f[B]\-\-warn\f[]) flags were not given on the command line, the max |
|
allowable value for \f[B]ibase\f[] is \f[B]36\f[]. |
|
Otherwise, it is \f[B]16\f[]. |
|
The min allowable value for \f[B]ibase\f[] is \f[B]2\f[]. |
|
The max allowable value for \f[B]ibase\f[] can be queried in bc(1) |
|
programs with the \f[B]maxibase()\f[] built\-in function. |
|
.PP |
|
\f[B]obase\f[] is a global variable determining how to output results. |
|
It is the "output" base, or the number base used for outputting numbers. |
|
\f[B]obase\f[] is initially \f[B]10\f[]. |
|
The max allowable value for \f[B]obase\f[] is \f[B]BC_BASE_MAX\f[] and |
|
can be queried in bc(1) programs with the \f[B]maxobase()\f[] built\-in |
|
function. |
|
The min allowable value for \f[B]obase\f[] is \f[B]0\f[]. |
|
If \f[B]obase\f[] is \f[B]0\f[], values are output in scientific |
|
notation, and if \f[B]obase\f[] is \f[B]1\f[], values are output in |
|
engineering notation. |
|
Otherwise, values are output in the specified base. |
|
.PP |
|
Outputting in scientific and engineering notations are |
|
\f[B]non\-portable extensions\f[]. |
|
.PP |
|
The \f[I]scale\f[] of an expression is the number of digits in the |
|
result of the expression right of the decimal point, and \f[B]scale\f[] |
|
is a global variable that sets the precision of any operations, with |
|
exceptions. |
|
\f[B]scale\f[] is initially \f[B]0\f[]. |
|
\f[B]scale\f[] cannot be negative. |
|
The max allowable value for \f[B]scale\f[] is \f[B]BC_SCALE_MAX\f[] and |
|
can be queried in bc(1) programs with the \f[B]maxscale()\f[] built\-in |
|
function. |
|
.PP |
|
bc(1) has both \f[I]global\f[] variables and \f[I]local\f[] variables. |
|
All \f[I]local\f[] variables are local to the function; they are |
|
parameters or are introduced in the \f[B]auto\f[] list of a function |
|
(see the \f[B]FUNCTIONS\f[] section). |
|
If a variable is accessed which is not a parameter or in the |
|
\f[B]auto\f[] list, it is assumed to be \f[I]global\f[]. |
|
If a parent function has a \f[I]local\f[] variable version of a variable |
|
that a child function considers \f[I]global\f[], the value of that |
|
\f[I]global\f[] variable in the child function is the value of the |
|
variable in the parent function, not the value of the actual |
|
\f[I]global\f[] variable. |
|
.PP |
|
All of the above applies to arrays as well. |
|
.PP |
|
The value of a statement that is an expression (i.e., any of the named |
|
expressions or operands) is printed unless the lowest precedence |
|
operator is an assignment operator \f[I]and\f[] the expression is |
|
notsurrounded by parentheses. |
|
.PP |
|
The value that is printed is also assigned to the special variable |
|
\f[B]last\f[]. |
|
A single dot (\f[B].\f[]) may also be used as a synonym for |
|
\f[B]last\f[]. |
|
These are \f[B]non\-portable extensions\f[]. |
|
.PP |
|
Either semicolons or newlines may separate statements. |
|
.SS Comments |
|
.PP |
|
There are two kinds of comments: |
|
.IP "1." 3 |
|
Block comments are enclosed in \f[B]/*\f[] and \f[B]*/\f[]. |
|
.IP "2." 3 |
|
Line comments go from \f[B]#\f[] until, and not including, the next |
|
newline. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.SS Named Expressions |
|
.PP |
|
The following are named expressions in bc(1): |
|
.IP "1." 3 |
|
Variables: \f[B]I\f[] |
|
.IP "2." 3 |
|
Array Elements: \f[B]I[E]\f[] |
|
.IP "3." 3 |
|
\f[B]ibase\f[] |
|
.IP "4." 3 |
|
\f[B]obase\f[] |
|
.IP "5." 3 |
|
\f[B]scale\f[] |
|
.IP "6." 3 |
|
\f[B]seed\f[] |
|
.IP "7." 3 |
|
\f[B]last\f[] or a single dot (\f[B].\f[]) |
|
.PP |
|
Numbers 6 and 7 are \f[B]non\-portable extensions\f[]. |
|
.PP |
|
The meaning of \f[B]seed\f[] is dependent on the current pseudo\-random |
|
number generator but is guaranteed to not change except for new major |
|
versions. |
|
.PP |
|
The \f[I]scale\f[] and sign of the value may be significant. |
|
.PP |
|
If a previously used \f[B]seed\f[] value is assigned to \f[B]seed\f[] |
|
and used again, the pseudo\-random number generator is guaranteed to |
|
produce the same sequence of pseudo\-random numbers as it did when the |
|
\f[B]seed\f[] value was previously used. |
|
.PP |
|
The exact value assigned to \f[B]seed\f[] is not guaranteed to be |
|
returned if \f[B]seed\f[] is queried again immediately. |
|
However, if \f[B]seed\f[] \f[I]does\f[] return a different value, both |
|
values, when assigned to \f[B]seed\f[], are guaranteed to produce the |
|
same sequence of pseudo\-random numbers. |
|
This means that certain values assigned to \f[B]seed\f[] will |
|
\f[I]not\f[] produce unique sequences of pseudo\-random numbers. |
|
The value of \f[B]seed\f[] will change after any use of the |
|
\f[B]rand()\f[] and \f[B]irand(E)\f[] operands (see the |
|
\f[I]Operands\f[] subsection below), except if the parameter passed to |
|
\f[B]irand(E)\f[] is \f[B]0\f[], \f[B]1\f[], or negative. |
|
.PP |
|
There is no limit to the length (number of significant decimal digits) |
|
or \f[I]scale\f[] of the value that can be assigned to \f[B]seed\f[]. |
|
.PP |
|
Variables and arrays do not interfere; users can have arrays named the |
|
same as variables. |
|
This also applies to functions (see the \f[B]FUNCTIONS\f[] section), so |
|
a user can have a variable, array, and function that all have the same |
|
name, and they will not shadow each other, whether inside of functions |
|
or not. |
|
.PP |
|
Named expressions are required as the operand of |
|
\f[B]increment\f[]/\f[B]decrement\f[] operators and as the left side of |
|
\f[B]assignment\f[] operators (see the \f[I]Operators\f[] subsection). |
|
.SS Operands |
|
.PP |
|
The following are valid operands in bc(1): |
|
.IP " 1." 4 |
|
Numbers (see the \f[I]Numbers\f[] subsection below). |
|
.IP " 2." 4 |
|
Array indices (\f[B]I[E]\f[]). |
|
.IP " 3." 4 |
|
\f[B](E)\f[]: The value of \f[B]E\f[] (used to change precedence). |
|
.IP " 4." 4 |
|
\f[B]sqrt(E)\f[]: The square root of \f[B]E\f[]. |
|
\f[B]E\f[] must be non\-negative. |
|
.IP " 5." 4 |
|
\f[B]length(E)\f[]: The number of significant decimal digits in |
|
\f[B]E\f[]. |
|
.IP " 6." 4 |
|
\f[B]length(I[])\f[]: The number of elements in the array \f[B]I\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP " 7." 4 |
|
\f[B]scale(E)\f[]: The \f[I]scale\f[] of \f[B]E\f[]. |
|
.IP " 8." 4 |
|
\f[B]abs(E)\f[]: The absolute value of \f[B]E\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP " 9." 4 |
|
\f[B]I()\f[], \f[B]I(E)\f[], \f[B]I(E, E)\f[], and so on, where |
|
\f[B]I\f[] is an identifier for a non\-\f[B]void\f[] function (see the |
|
\f[I]Void Functions\f[] subsection of the \f[B]FUNCTIONS\f[] section). |
|
The \f[B]E\f[] argument(s) may also be arrays of the form \f[B]I[]\f[], |
|
which will automatically be turned into array references (see the |
|
\f[I]Array References\f[] subsection of the \f[B]FUNCTIONS\f[] section) |
|
if the corresponding parameter in the function definition is an array |
|
reference. |
|
.IP "10." 4 |
|
\f[B]read()\f[]: Reads a line from \f[B]stdin\f[] and uses that as an |
|
expression. |
|
The result of that expression is the result of the \f[B]read()\f[] |
|
operand. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP "11." 4 |
|
\f[B]maxibase()\f[]: The max allowable \f[B]ibase\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP "12." 4 |
|
\f[B]maxobase()\f[]: The max allowable \f[B]obase\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP "13." 4 |
|
\f[B]maxscale()\f[]: The max allowable \f[B]scale\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP "14." 4 |
|
\f[B]rand()\f[]: A pseudo\-random integer between \f[B]0\f[] (inclusive) |
|
and \f[B]BC_RAND_MAX\f[] (inclusive). |
|
Using this operand will change the value of \f[B]seed\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP "15." 4 |
|
\f[B]irand(E)\f[]: A pseudo\-random integer between \f[B]0\f[] |
|
(inclusive) and the value of \f[B]E\f[] (exclusive). |
|
If \f[B]E\f[] is negative or is a non\-integer (\f[B]E\f[]\[aq]s |
|
\f[I]scale\f[] is not \f[B]0\f[]), an error is raised, and bc(1) resets |
|
(see the \f[B]RESET\f[] section) while \f[B]seed\f[] remains unchanged. |
|
If \f[B]E\f[] is larger than \f[B]BC_RAND_MAX\f[], the higher bound is |
|
honored by generating several pseudo\-random integers, multiplying them |
|
by appropriate powers of \f[B]BC_RAND_MAX+1\f[], and adding them |
|
together. |
|
Thus, the size of integer that can be generated with this operand is |
|
unbounded. |
|
Using this operand will change the value of \f[B]seed\f[], unless the |
|
value of \f[B]E\f[] is \f[B]0\f[] or \f[B]1\f[]. |
|
In that case, \f[B]0\f[] is returned, and \f[B]seed\f[] is \f[I]not\f[] |
|
changed. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.IP "16." 4 |
|
\f[B]maxrand()\f[]: The max integer returned by \f[B]rand()\f[]. |
|
This is a \f[B]non\-portable extension\f[]. |
|
.PP |
|
The integers generated by \f[B]rand()\f[] and \f[B]irand(E)\f[] are |
|
guaranteed to be as unbiased as possible, subject to the limitations of |
|
the pseudo\-random number generator. |
|
.PP |
|
\f[B]Note\f[]: The values returned by the pseudo\-random number |
|
generator with \f[B]rand()\f[] and \f[B]irand(E)\f[] are guaranteed to |
|
\f[I]NOT\f[] be cryptographically secure. |
|
This is a consequence of using a seeded pseudo\-random number generator. |
|
However, they \f[I]are\f[] guaranteed to be reproducible with identical |
|
\f[B]seed\f[] values. |
|
.SS Numbers |
|
.PP |
|
Numbers are strings made up of digits, uppercase letters, and at most |
|
\f[B]1\f[] period for a radix. |
|
Numbers can have up to \f[B]BC_NUM_MAX\f[] digits. |
|
Uppercase letters are equal to \f[B]9\f[] + their position in the |
|
alphabet (i.e., \f[B]A\f[] equals \f[B]10\f[], or \f[B]9+1\f[]). |
|
If a digit or letter makes no sense with the current value of |
|
\f[B]ibase\f[], they are set to the value of the highest valid digit in |
|
\f[B]ibase\f[]. |
|
.PP |
|
Single\-character numbers (i.e., \f[B]A\f[] alone) take the value that |
|
they would have if they were valid digits, regardless of the value of |
|
\f[B]ibase\f[]. |
|
This means that \f[B]A\f[] alone always equals decimal \f[B]10\f[] and |
|
\f[B]Z\f[] alone always equals decimal \f[B]35\f[]. |
|
.PP |
|
In addition, bc(1) accepts numbers in scientific notation. |
|
These have the form \f[B]<number>e<integer>\f[]. |
|
The power (the portion after the \f[B]e\f[]) must be an integer. |
|
An example is \f[B]1.89237e9\f[], which is equal to \f[B]1892370000\f[]. |
|
Negative exponents are also allowed, so \f[B]4.2890e\-3\f[] is equal to |
|
\f[B]0.0042890\f[]. |
|
.PP |
|
Using scientific notation is an error or warning if the \f[B]\-s\f[] or |
|
\f[B]\-w\f[], respectively, command\-line options (or equivalents) are |
|
given. |
|
.PP |
|
\f[B]WARNING\f[]: Both the number and the exponent in scientific |
|
notation are interpreted according to the current \f[B]ibase\f[], but |
|
the number is still multiplied by \f[B]10^exponent\f[] regardless of the |
|
current \f[B]ibase\f[]. |
|
For example, if \f[B]ibase\f[] is \f[B]16\f[] and bc(1) is given the |
|
number string \f[B]FFeA\f[], the resulting decimal number will be |
|
\f[B]2550000000000\f[], and if bc(1) is given the number string |
|
\f[B]10e\-4\f[], the resulting decimal number will be \f[B]0.0016\f[]. |
|
.PP |
|
Accepting input as scientific notation is a \f[B]non\-portable |
|
extension\f[]. |
|
.SS Operators |
|
.PP |
|
The following arithmetic and logical operators can be used. |
|
They are listed in order of decreasing precedence. |
|
Operators in the same group have the same precedence. |
|
.IP \[bu] 2 |
|
\f[B]++\f[] \f[B]\-\-\f[] |
|
.RS 2 |
|
.PP |
|
Type: Prefix and Postfix |
|
.PP |
|
Associativity: None |
|
.PP |
|
Description: \f[B]increment\f[], \f[B]decrement\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-\f[] \f[B]!\f[] |
|
.RS 2 |
|
.PP |
|
Type: Prefix |
|
.PP |
|
Associativity: None |
|
.PP |
|
Description: \f[B]negation\f[], \f[B]boolean not\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]$\f[] |
|
.RS 2 |
|
.PP |
|
Type: Postfix |
|
.PP |
|
Associativity: None |
|
.PP |
|
Description: \f[B]truncation\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\@\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Right |
|
.PP |
|
Description: \f[B]set precision\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]^\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Right |
|
.PP |
|
Description: \f[B]power\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]*\f[] \f[B]/\f[] \f[B]%\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Left |
|
.PP |
|
Description: \f[B]multiply\f[], \f[B]divide\f[], \f[B]modulus\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]+\f[] \f[B]\-\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Left |
|
.PP |
|
Description: \f[B]add\f[], \f[B]subtract\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]<<\f[] \f[B]>>\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Left |
|
.PP |
|
Description: \f[B]shift left\f[], \f[B]shift right\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]=\f[] \f[B]<<=\f[] \f[B]>>=\f[] \f[B]+=\f[] \f[B]\-=\f[] |
|
\f[B]*=\f[] \f[B]/=\f[] \f[B]%=\f[] \f[B]^=\f[] \f[B]\@=\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Right |
|
.PP |
|
Description: \f[B]assignment\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]==\f[] \f[B]<=\f[] \f[B]>=\f[] \f[B]!=\f[] \f[B]<\f[] \f[B]>\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Left |
|
.PP |
|
Description: \f[B]relational\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]&&\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Left |
|
.PP |
|
Description: \f[B]boolean and\f[] |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]||\f[] |
|
.RS 2 |
|
.PP |
|
Type: Binary |
|
.PP |
|
Associativity: Left |
|
.PP |
|
Description: \f[B]boolean or\f[] |
|
.RE |
|
.PP |
|
The operators will be described in more detail below. |
|
.IP \[bu] 2 |
|
\f[B]++\f[] \f[B]\-\-\f[] |
|
.RS 2 |
|
.PP |
|
The prefix and postfix \f[B]increment\f[] and \f[B]decrement\f[] |
|
operators behave exactly like they would in C. |
|
They require a named expression (see the \f[I]Named Expressions\f[] |
|
subsection) as an operand. |
|
.PP |
|
The prefix versions of these operators are more efficient; use them |
|
where possible. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]negation\f[] operator returns \f[B]0\f[] if a user attempts to |
|
negate any expression with the value \f[B]0\f[]. |
|
Otherwise, a copy of the expression with its sign flipped is returned. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]!\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]boolean not\f[] operator returns \f[B]1\f[] if the expression |
|
is \f[B]0\f[], or \f[B]0\f[] otherwise. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]$\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]truncation\f[] operator returns a copy of the given expression |
|
with all of its \f[I]scale\f[] removed. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\@\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]set precision\f[] operator takes two expressions and returns a |
|
copy of the first with its \f[I]scale\f[] equal to the value of the |
|
second expression. |
|
That could either mean that the number is returned without change (if |
|
the \f[I]scale\f[] of the first expression matches the value of the |
|
second expression), extended (if it is less), or truncated (if it is |
|
more). |
|
.PP |
|
The second expression must be an integer (no \f[I]scale\f[]) and |
|
non\-negative. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]^\f[] |
|
.RS 2 |
|
The \f[B]power\f[] operator (not the \f[B]exclusive or\f[] operator, as |
|
it would be in |
|
.IP "C)" 3 |
|
takes two expressions and raises the first to the power of the value of |
|
the second. |
|
.PP |
|
The second expression must be an integer (no \f[I]scale\f[]), and if it |
|
is negative, the first value must be non\-zero. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]*\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]multiply\f[] operator takes two expressions, multiplies them, |
|
and returns the product. |
|
If \f[B]a\f[] is the \f[I]scale\f[] of the first expression and |
|
\f[B]b\f[] is the \f[I]scale\f[] of the second expression, the |
|
\f[I]scale\f[] of the result is equal to |
|
\f[B]min(a+b,max(scale,a,b))\f[] where \f[B]min()\f[] and \f[B]max()\f[] |
|
return the obvious values. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]/\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]divide\f[] operator takes two expressions, divides them, and |
|
returns the quotient. |
|
The \f[I]scale\f[] of the result shall be the value of \f[B]scale\f[]. |
|
.PP |
|
The second expression must be non\-zero. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]%\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]modulus\f[] operator takes two expressions, \f[B]a\f[] and |
|
\f[B]b\f[], and evaluates them by 1) Computing \f[B]a/b\f[] to current |
|
\f[B]scale\f[] and 2) Using the result of step 1 to calculate |
|
\f[B]a\-(a/b)*b\f[] to \f[I]scale\f[] |
|
\f[B]max(scale+scale(b),scale(a))\f[]. |
|
.PP |
|
The second expression must be non\-zero. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]+\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]add\f[] operator takes two expressions, \f[B]a\f[] and |
|
\f[B]b\f[], and returns the sum, with a \f[I]scale\f[] equal to the max |
|
of the \f[I]scale\f[]s of \f[B]a\f[] and \f[B]b\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]\-\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]subtract\f[] operator takes two expressions, \f[B]a\f[] and |
|
\f[B]b\f[], and returns the difference, with a \f[I]scale\f[] equal to |
|
the max of the \f[I]scale\f[]s of \f[B]a\f[] and \f[B]b\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]<<\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]left shift\f[] operator takes two expressions, \f[B]a\f[] and |
|
\f[B]b\f[], and returns a copy of the value of \f[B]a\f[] with its |
|
decimal point moved \f[B]b\f[] places to the right. |
|
.PP |
|
The second expression must be an integer (no \f[I]scale\f[]) and |
|
non\-negative. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]>>\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]right shift\f[] operator takes two expressions, \f[B]a\f[] and |
|
\f[B]b\f[], and returns a copy of the value of \f[B]a\f[] with its |
|
decimal point moved \f[B]b\f[] places to the left. |
|
.PP |
|
The second expression must be an integer (no \f[I]scale\f[]) and |
|
non\-negative. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]=\f[] \f[B]<<=\f[] \f[B]>>=\f[] \f[B]+=\f[] \f[B]\-=\f[] |
|
\f[B]*=\f[] \f[B]/=\f[] \f[B]%=\f[] \f[B]^=\f[] \f[B]\@=\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]assignment\f[] operators take two expressions, \f[B]a\f[] and |
|
\f[B]b\f[] where \f[B]a\f[] is a named expression (see the \f[I]Named |
|
Expressions\f[] subsection). |
|
.PP |
|
For \f[B]=\f[], \f[B]b\f[] is copied and the result is assigned to |
|
\f[B]a\f[]. |
|
For all others, \f[B]a\f[] and \f[B]b\f[] are applied as operands to the |
|
corresponding arithmetic operator and the result is assigned to |
|
\f[B]a\f[]. |
|
.PP |
|
The \f[B]assignment\f[] operators that correspond to operators that are |
|
extensions are themselves \f[B]non\-portable extensions\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]==\f[] \f[B]<=\f[] \f[B]>=\f[] \f[B]!=\f[] \f[B]<\f[] \f[B]>\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]relational\f[] operators compare two expressions, \f[B]a\f[] |
|
and \f[B]b\f[], and if the relation holds, according to C language |
|
semantics, the result is \f[B]1\f[]. |
|
Otherwise, it is \f[B]0\f[]. |
|
.PP |
|
Note that unlike in C, these operators have a lower precedence than the |
|
\f[B]assignment\f[] operators, which means that \f[B]a=b>c\f[] is |
|
interpreted as \f[B](a=b)>c\f[]. |
|
.PP |
|
Also, unlike the |
|
standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) |
|
requires, these operators can appear anywhere any other expressions can |
|
be used. |
|
This allowance is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]&&\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]boolean and\f[] operator takes two expressions and returns |
|
\f[B]1\f[] if both expressions are non\-zero, \f[B]0\f[] otherwise. |
|
.PP |
|
This is \f[I]not\f[] a short\-circuit operator. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]||\f[] |
|
.RS 2 |
|
.PP |
|
The \f[B]boolean or\f[] operator takes two expressions and returns |
|
\f[B]1\f[] if one of the expressions is non\-zero, \f[B]0\f[] otherwise. |
|
.PP |
|
This is \f[I]not\f[] a short\-circuit operator. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.RE |
|
.SS Statements |
|
.PP |
|
The following items are statements: |
|
.IP " 1." 4 |
|
\f[B]E\f[] |
|
.IP " 2." 4 |
|
\f[B]{\f[] \f[B]S\f[] \f[B];\f[] ... |
|
\f[B];\f[] \f[B]S\f[] \f[B]}\f[] |
|
.IP " 3." 4 |
|
\f[B]if\f[] \f[B](\f[] \f[B]E\f[] \f[B])\f[] \f[B]S\f[] |
|
.IP " 4." 4 |
|
\f[B]if\f[] \f[B](\f[] \f[B]E\f[] \f[B])\f[] \f[B]S\f[] \f[B]else\f[] |
|
\f[B]S\f[] |
|
.IP " 5." 4 |
|
\f[B]while\f[] \f[B](\f[] \f[B]E\f[] \f[B])\f[] \f[B]S\f[] |
|
.IP " 6." 4 |
|
\f[B]for\f[] \f[B](\f[] \f[B]E\f[] \f[B];\f[] \f[B]E\f[] \f[B];\f[] |
|
\f[B]E\f[] \f[B])\f[] \f[B]S\f[] |
|
.IP " 7." 4 |
|
An empty statement |
|
.IP " 8." 4 |
|
\f[B]break\f[] |
|
.IP " 9." 4 |
|
\f[B]continue\f[] |
|
.IP "10." 4 |
|
\f[B]quit\f[] |
|
.IP "11." 4 |
|
\f[B]halt\f[] |
|
.IP "12." 4 |
|
\f[B]limits\f[] |
|
.IP "13." 4 |
|
A string of characters, enclosed in double quotes |
|
.IP "14." 4 |
|
\f[B]print\f[] \f[B]E\f[] \f[B],\f[] ... |
|
\f[B],\f[] \f[B]E\f[] |
|
.IP "15." 4 |
|
\f[B]I()\f[], \f[B]I(E)\f[], \f[B]I(E, E)\f[], and so on, where |
|
\f[B]I\f[] is an identifier for a \f[B]void\f[] function (see the |
|
\f[I]Void Functions\f[] subsection of the \f[B]FUNCTIONS\f[] section). |
|
The \f[B]E\f[] argument(s) may also be arrays of the form \f[B]I[]\f[], |
|
which will automatically be turned into array references (see the |
|
\f[I]Array References\f[] subsection of the \f[B]FUNCTIONS\f[] section) |
|
if the corresponding parameter in the function definition is an array |
|
reference. |
|
.PP |
|
Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non\-portable extensions\f[]. |
|
.PP |
|
Also, as a \f[B]non\-portable extension\f[], any or all of the |
|
expressions in the header of a for loop may be omitted. |
|
If the condition (second expression) is omitted, it is assumed to be a |
|
constant \f[B]1\f[]. |
|
.PP |
|
The \f[B]break\f[] statement causes a loop to stop iterating and resume |
|
execution immediately following a loop. |
|
This is only allowed in loops. |
|
.PP |
|
The \f[B]continue\f[] statement causes a loop iteration to stop early |
|
and returns to the start of the loop, including testing the loop |
|
condition. |
|
This is only allowed in loops. |
|
.PP |
|
The \f[B]if\f[] \f[B]else\f[] statement does the same thing as in C. |
|
.PP |
|
The \f[B]quit\f[] statement causes bc(1) to quit, even if it is on a |
|
branch that will not be executed (it is a compile\-time command). |
|
.PP |
|
The \f[B]halt\f[] statement causes bc(1) to quit, if it is executed. |
|
(Unlike \f[B]quit\f[] if it is on a branch of an \f[B]if\f[] statement |
|
that is not executed, bc(1) does not quit.) |
|
.PP |
|
The \f[B]limits\f[] statement prints the limits that this bc(1) is |
|
subject to. |
|
This is like the \f[B]quit\f[] statement in that it is a compile\-time |
|
command. |
|
.PP |
|
An expression by itself is evaluated and printed, followed by a newline. |
|
.PP |
|
Both scientific notation and engineering notation are available for |
|
printing the results of expressions. |
|
Scientific notation is activated by assigning \f[B]0\f[] to |
|
\f[B]obase\f[], and engineering notation is activated by assigning |
|
\f[B]1\f[] to \f[B]obase\f[]. |
|
To deactivate them, just assign a different value to \f[B]obase\f[]. |
|
.PP |
|
Scientific notation and engineering notation are disabled if bc(1) is |
|
run with either the \f[B]\-s\f[] or \f[B]\-w\f[] command\-line options |
|
(or equivalents). |
|
.PP |
|
Printing numbers in scientific notation and/or engineering notation is a |
|
\f[B]non\-portable extension\f[]. |
|
.SS Print Statement |
|
.PP |
|
The "expressions" in a \f[B]print\f[] statement may also be strings. |
|
If they are, there are backslash escape sequences that are interpreted |
|
specially. |
|
What those sequences are, and what they cause to be printed, are shown |
|
below: |
|
.IP \[bu] 2 |
|
\f[B]\\a\f[]: \f[B]\\a\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\b\f[]: \f[B]\\b\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\\\\f[]: \f[B]\\\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\e\f[]: \f[B]\\\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\f\f[]: \f[B]\\f\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\n\f[]: \f[B]\\n\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\q\f[]: \f[B]"\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\r\f[]: \f[B]\\r\f[] |
|
.IP \[bu] 2 |
|
\f[B]\\t\f[]: \f[B]\\t\f[] |
|
.PP |
|
Any other character following a backslash causes the backslash and |
|
character to be printed as\-is. |
|
.PP |
|
Any non\-string expression in a print statement shall be assigned to |
|
\f[B]last\f[], like any other expression that is printed. |
|
.SS Order of Evaluation |
|
.PP |
|
All expressions in a statment are evaluated left to right, except as |
|
necessary to maintain order of operations. |
|
This means, for example, assuming that \f[B]i\f[] is equal to |
|
\f[B]0\f[], in the expression |
|
.IP |
|
.nf |
|
\f[C] |
|
a[i++]\ =\ i++ |
|
\f[] |
|
.fi |
|
.PP |
|
the first (or 0th) element of \f[B]a\f[] is set to \f[B]1\f[], and |
|
\f[B]i\f[] is equal to \f[B]2\f[] at the end of the expression. |
|
.PP |
|
This includes function arguments. |
|
Thus, assuming \f[B]i\f[] is equal to \f[B]0\f[], this means that in the |
|
expression |
|
.IP |
|
.nf |
|
\f[C] |
|
x(i++,\ i++) |
|
\f[] |
|
.fi |
|
.PP |
|
the first argument passed to \f[B]x()\f[] is \f[B]0\f[], and the second |
|
argument is \f[B]1\f[], while \f[B]i\f[] is equal to \f[B]2\f[] before |
|
the function starts executing. |
|
.SH FUNCTIONS |
|
.PP |
|
Function definitions are as follows: |
|
.IP |
|
.nf |
|
\f[C] |
|
define\ I(I,...,I){ |
|
\ \ \ \ auto\ I,...,I |
|
\ \ \ \ S;...;S |
|
\ \ \ \ return(E) |
|
} |
|
\f[] |
|
.fi |
|
.PP |
|
Any \f[B]I\f[] in the parameter list or \f[B]auto\f[] list may be |
|
replaced with \f[B]I[]\f[] to make a parameter or \f[B]auto\f[] var an |
|
array, and any \f[B]I\f[] in the parameter list may be replaced with |
|
\f[B]*I[]\f[] to make a parameter an array reference. |
|
Callers of functions that take array references should not put an |
|
asterisk in the call; they must be called with just \f[B]I[]\f[] like |
|
normal array parameters and will be automatically converted into |
|
references. |
|
.PP |
|
As a \f[B]non\-portable extension\f[], the opening brace of a |
|
\f[B]define\f[] statement may appear on the next line. |
|
.PP |
|
As a \f[B]non\-portable extension\f[], the return statement may also be |
|
in one of the following forms: |
|
.IP "1." 3 |
|
\f[B]return\f[] |
|
.IP "2." 3 |
|
\f[B]return\f[] \f[B](\f[] \f[B])\f[] |
|
.IP "3." 3 |
|
\f[B]return\f[] \f[B]E\f[] |
|
.PP |
|
The first two, or not specifying a \f[B]return\f[] statement, is |
|
equivalent to \f[B]return (0)\f[], unless the function is a |
|
\f[B]void\f[] function (see the \f[I]Void Functions\f[] subsection |
|
below). |
|
.SS Void Functions |
|
.PP |
|
Functions can also be \f[B]void\f[] functions, defined as follows: |
|
.IP |
|
.nf |
|
\f[C] |
|
define\ void\ I(I,...,I){ |
|
\ \ \ \ auto\ I,...,I |
|
\ \ \ \ S;...;S |
|
\ \ \ \ return |
|
} |
|
\f[] |
|
.fi |
|
.PP |
|
They can only be used as standalone expressions, where such an |
|
expression would be printed alone, except in a print statement. |
|
.PP |
|
Void functions can only use the first two \f[B]return\f[] statements |
|
listed above. |
|
They can also omit the return statement entirely. |
|
.PP |
|
The word "void" is not treated as a keyword; it is still possible to |
|
have variables, arrays, and functions named \f[B]void\f[]. |
|
The word "void" is only treated specially right after the |
|
\f[B]define\f[] keyword. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.SS Array References |
|
.PP |
|
For any array in the parameter list, if the array is declared in the |
|
form |
|
.IP |
|
.nf |
|
\f[C] |
|
*I[] |
|
\f[] |
|
.fi |
|
.PP |
|
it is a \f[B]reference\f[]. |
|
Any changes to the array in the function are reflected, when the |
|
function returns, to the array that was passed in. |
|
.PP |
|
Other than this, all function arguments are passed by value. |
|
.PP |
|
This is a \f[B]non\-portable extension\f[]. |
|
.SH LIBRARY |
|
.PP |
|
All of the functions below, including the functions in the extended math |
|
library (see the \f[I]Extended Library\f[] subsection below), are |
|
available when the \f[B]\-l\f[] or \f[B]\-\-mathlib\f[] command\-line |
|
flags are given, except that the extended math library is not available |
|
when the \f[B]\-s\f[] option, the \f[B]\-w\f[] option, or equivalents |
|
are given. |
|
.SS Standard Library |
|
.PP |
|
The |
|
standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) |
|
defines the following functions for the math library: |
|
.IP \[bu] 2 |
|
\f[B]s(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the sine of \f[B]x\f[], which is assumed to be in radians. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]c(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the cosine of \f[B]x\f[], which is assumed to be in radians. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]a(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the arctangent of \f[B]x\f[], in radians. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]l(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the natural logarithm of \f[B]x\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]e(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the mathematical constant \f[B]e\f[] raised to the power of |
|
\f[B]x\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]j(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the bessel integer order \f[B]n\f[] (truncated) of \f[B]x\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.SS Extended Library |
|
.PP |
|
The extended library is \f[I]not\f[] loaded when the |
|
\f[B]\-s\f[]/\f[B]\-\-standard\f[] or \f[B]\-w\f[]/\f[B]\-\-warn\f[] |
|
options are given since they are not part of the library defined by the |
|
standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). |
|
.PP |
|
The extended library is a \f[B]non\-portable extension\f[]. |
|
.IP \[bu] 2 |
|
\f[B]p(x, y)\f[] |
|
.RS 2 |
|
.PP |
|
Calculates \f[B]x\f[] to the power of \f[B]y\f[], even if \f[B]y\f[] is |
|
not an integer, and returns the result to the current \f[B]scale\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]r(x, p)\f[] |
|
.RS 2 |
|
.PP |
|
Returns \f[B]x\f[] rounded to \f[B]p\f[] decimal places according to the |
|
rounding mode round half away from |
|
\f[B]0\f[] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]ceil(x, p)\f[] |
|
.RS 2 |
|
.PP |
|
Returns \f[B]x\f[] rounded to \f[B]p\f[] decimal places according to the |
|
rounding mode round away from |
|
\f[B]0\f[] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]f(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the factorial of the truncated absolute value of \f[B]x\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]perm(n, k)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the permutation of the truncated absolute value of \f[B]n\f[] of |
|
the truncated absolute value of \f[B]k\f[], if \f[B]k <= n\f[]. |
|
If not, it returns \f[B]0\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]comb(n, k)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the combination of the truncated absolute value of \f[B]n\f[] of |
|
the truncated absolute value of \f[B]k\f[], if \f[B]k <= n\f[]. |
|
If not, it returns \f[B]0\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]l2(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the logarithm base \f[B]2\f[] of \f[B]x\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]l10(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the logarithm base \f[B]10\f[] of \f[B]x\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]log(x, b)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the logarithm base \f[B]b\f[] of \f[B]x\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]cbrt(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the cube root of \f[B]x\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]root(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Calculates the truncated value of \f[B]n\f[], \f[B]r\f[], and returns |
|
the \f[B]r\f[]th root of \f[B]x\f[] to the current \f[B]scale\f[]. |
|
.PP |
|
If \f[B]r\f[] is \f[B]0\f[] or negative, this raises an error and causes |
|
bc(1) to reset (see the \f[B]RESET\f[] section). |
|
It also raises an error and causes bc(1) to reset if \f[B]r\f[] is even |
|
and \f[B]x\f[] is negative. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]pi(p)\f[] |
|
.RS 2 |
|
.PP |
|
Returns \f[B]pi\f[] to \f[B]p\f[] decimal places. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]t(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the tangent of \f[B]x\f[], which is assumed to be in radians. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]a2(y, x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the arctangent of \f[B]y/x\f[], in radians. |
|
If both \f[B]y\f[] and \f[B]x\f[] are equal to \f[B]0\f[], it raises an |
|
error and causes bc(1) to reset (see the \f[B]RESET\f[] section). |
|
Otherwise, if \f[B]x\f[] is greater than \f[B]0\f[], it returns |
|
\f[B]a(y/x)\f[]. |
|
If \f[B]x\f[] is less than \f[B]0\f[], and \f[B]y\f[] is greater than or |
|
equal to \f[B]0\f[], it returns \f[B]a(y/x)+pi\f[]. |
|
If \f[B]x\f[] is less than \f[B]0\f[], and \f[B]y\f[] is less than |
|
\f[B]0\f[], it returns \f[B]a(y/x)\-pi\f[]. |
|
If \f[B]x\f[] is equal to \f[B]0\f[], and \f[B]y\f[] is greater than |
|
\f[B]0\f[], it returns \f[B]pi/2\f[]. |
|
If \f[B]x\f[] is equal to \f[B]0\f[], and \f[B]y\f[] is less than |
|
\f[B]0\f[], it returns \f[B]\-pi/2\f[]. |
|
.PP |
|
This function is the same as the \f[B]atan2()\f[] function in many |
|
programming languages. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]sin(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the sine of \f[B]x\f[], which is assumed to be in radians. |
|
.PP |
|
This is an alias of \f[B]s(x)\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]cos(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the cosine of \f[B]x\f[], which is assumed to be in radians. |
|
.PP |
|
This is an alias of \f[B]c(x)\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]tan(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the tangent of \f[B]x\f[], which is assumed to be in radians. |
|
.PP |
|
If \f[B]x\f[] is equal to \f[B]1\f[] or \f[B]\-1\f[], this raises an |
|
error and causes bc(1) to reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is an alias of \f[B]t(x)\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]atan(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the arctangent of \f[B]x\f[], in radians. |
|
.PP |
|
This is an alias of \f[B]a(x)\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]atan2(y, x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the arctangent of \f[B]y/x\f[], in radians. |
|
If both \f[B]y\f[] and \f[B]x\f[] are equal to \f[B]0\f[], it raises an |
|
error and causes bc(1) to reset (see the \f[B]RESET\f[] section). |
|
Otherwise, if \f[B]x\f[] is greater than \f[B]0\f[], it returns |
|
\f[B]a(y/x)\f[]. |
|
If \f[B]x\f[] is less than \f[B]0\f[], and \f[B]y\f[] is greater than or |
|
equal to \f[B]0\f[], it returns \f[B]a(y/x)+pi\f[]. |
|
If \f[B]x\f[] is less than \f[B]0\f[], and \f[B]y\f[] is less than |
|
\f[B]0\f[], it returns \f[B]a(y/x)\-pi\f[]. |
|
If \f[B]x\f[] is equal to \f[B]0\f[], and \f[B]y\f[] is greater than |
|
\f[B]0\f[], it returns \f[B]pi/2\f[]. |
|
If \f[B]x\f[] is equal to \f[B]0\f[], and \f[B]y\f[] is less than |
|
\f[B]0\f[], it returns \f[B]\-pi/2\f[]. |
|
.PP |
|
This function is the same as the \f[B]atan2()\f[] function in many |
|
programming languages. |
|
.PP |
|
This is an alias of \f[B]a2(y, x)\f[]. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]r2d(x)\f[] |
|
.RS 2 |
|
.PP |
|
Converts \f[B]x\f[] from radians to degrees and returns the result. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]d2r(x)\f[] |
|
.RS 2 |
|
.PP |
|
Converts \f[B]x\f[] from degrees to radians and returns the result. |
|
.PP |
|
This is a transcendental function (see the \f[I]Transcendental |
|
Functions\f[] subsection below). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]frand(p)\f[] |
|
.RS 2 |
|
.PP |
|
Generates a pseudo\-random number between \f[B]0\f[] (inclusive) and |
|
\f[B]1\f[] (exclusive) with the number of decimal digits after the |
|
decimal point equal to the truncated absolute value of \f[B]p\f[]. |
|
If \f[B]p\f[] is not \f[B]0\f[], then calling this function will change |
|
the value of \f[B]seed\f[]. |
|
If \f[B]p\f[] is \f[B]0\f[], then \f[B]0\f[] is returned, and |
|
\f[B]seed\f[] is \f[I]not\f[] changed. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]ifrand(i, p)\f[] |
|
.RS 2 |
|
.PP |
|
Generates a pseudo\-random number that is between \f[B]0\f[] (inclusive) |
|
and the truncated absolute value of \f[B]i\f[] (exclusive) with the |
|
number of decimal digits after the decimal point equal to the truncated |
|
absolute value of \f[B]p\f[]. |
|
If the absolute value of \f[B]i\f[] is greater than or equal to |
|
\f[B]2\f[], and \f[B]p\f[] is not \f[B]0\f[], then calling this function |
|
will change the value of \f[B]seed\f[]; otherwise, \f[B]0\f[] is |
|
returned and \f[B]seed\f[] is not changed. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]srand(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns \f[B]x\f[] with its sign flipped with probability \f[B]0.5\f[]. |
|
In other words, it randomizes the sign of \f[B]x\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]brand()\f[] |
|
.RS 2 |
|
.PP |
|
Returns a random boolean value (either \f[B]0\f[] or \f[B]1\f[]). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]ubytes(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the numbers of unsigned integer bytes required to hold the |
|
truncated absolute value of \f[B]x\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]sbytes(x)\f[] |
|
.RS 2 |
|
.PP |
|
Returns the numbers of signed, two\[aq]s\-complement integer bytes |
|
required to hold the truncated value of \f[B]x\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]hex(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the hexadecimal (base \f[B]16\f[]) representation of \f[B]x\f[]. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]binary(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the binary (base \f[B]2\f[]) representation of \f[B]x\f[]. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]output(x, b)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the base \f[B]b\f[] representation of \f[B]x\f[]. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]uint(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
an unsigned integer in as few power of two bytes as possible. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer or is negative, an error message is |
|
printed instead, but bc(1) is not reset (see the \f[B]RESET\f[] |
|
section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]int(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
a signed, two\[aq]s\-complement integer in as few power of two bytes as |
|
possible. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer, an error message is printed instead, |
|
but bc(1) is not reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]uintn(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
an unsigned integer in \f[B]n\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer, is negative, or cannot fit into |
|
\f[B]n\f[] bytes, an error message is printed instead, but bc(1) is not |
|
reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]intn(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
a signed, two\[aq]s\-complement integer in \f[B]n\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer or cannot fit into \f[B]n\f[] bytes, an |
|
error message is printed instead, but bc(1) is not reset (see the |
|
\f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]uint8(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
an unsigned integer in \f[B]1\f[] byte. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer, is negative, or cannot fit into |
|
\f[B]1\f[] byte, an error message is printed instead, but bc(1) is not |
|
reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]int8(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
a signed, two\[aq]s\-complement integer in \f[B]1\f[] byte. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer or cannot fit into \f[B]1\f[] byte, an |
|
error message is printed instead, but bc(1) is not reset (see the |
|
\f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]uint16(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
an unsigned integer in \f[B]2\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer, is negative, or cannot fit into |
|
\f[B]2\f[] bytes, an error message is printed instead, but bc(1) is not |
|
reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]int16(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
a signed, two\[aq]s\-complement integer in \f[B]2\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer or cannot fit into \f[B]2\f[] bytes, an |
|
error message is printed instead, but bc(1) is not reset (see the |
|
\f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]uint32(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
an unsigned integer in \f[B]4\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer, is negative, or cannot fit into |
|
\f[B]4\f[] bytes, an error message is printed instead, but bc(1) is not |
|
reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]int32(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
a signed, two\[aq]s\-complement integer in \f[B]4\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer or cannot fit into \f[B]4\f[] bytes, an |
|
error message is printed instead, but bc(1) is not reset (see the |
|
\f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]uint64(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
an unsigned integer in \f[B]8\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer, is negative, or cannot fit into |
|
\f[B]8\f[] bytes, an error message is printed instead, but bc(1) is not |
|
reset (see the \f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]int64(x)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation, in binary and hexadecimal, of \f[B]x\f[] as |
|
a signed, two\[aq]s\-complement integer in \f[B]8\f[] bytes. |
|
Both outputs are split into bytes separated by spaces. |
|
.PP |
|
If \f[B]x\f[] is not an integer or cannot fit into \f[B]8\f[] bytes, an |
|
error message is printed instead, but bc(1) is not reset (see the |
|
\f[B]RESET\f[] section). |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]hex_uint(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation of the truncated absolute value of \f[B]x\f[] |
|
as an unsigned integer in hexadecimal using \f[B]n\f[] bytes. |
|
Not all of the value will be output if \f[B]n\f[] is too small. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]binary_uint(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation of the truncated absolute value of \f[B]x\f[] |
|
as an unsigned integer in binary using \f[B]n\f[] bytes. |
|
Not all of the value will be output if \f[B]n\f[] is too small. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]output_uint(x, n)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs the representation of the truncated absolute value of \f[B]x\f[] |
|
as an unsigned integer in the current \f[B]obase\f[] (see the |
|
\f[B]SYNTAX\f[] section) using \f[B]n\f[] bytes. |
|
Not all of the value will be output if \f[B]n\f[] is too small. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]output_byte(x, i)\f[] |
|
.RS 2 |
|
.PP |
|
Outputs byte \f[B]i\f[] of the truncated absolute value of \f[B]x\f[], |
|
where \f[B]0\f[] is the least significant byte and \f[B]number_of_bytes |
|
\- 1\f[] is the most significant byte. |
|
.PP |
|
This is a \f[B]void\f[] function (see the \f[I]Void Functions\f[] |
|
subsection of the \f[B]FUNCTIONS\f[] section). |
|
.RE |
|
.SS Transcendental Functions |
|
.PP |
|
All transcendental functions can return slightly inaccurate results (up |
|
to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)). |
|
This is unavoidable, and this |
|
article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains |
|
why it is impossible and unnecessary to calculate exact results for the |
|
transcendental functions. |
|
.PP |
|
Because of the possible inaccuracy, I recommend that users call those |
|
functions with the precision (\f[B]scale\f[]) set to at least 1 higher |
|
than is necessary. |
|
If exact results are \f[I]absolutely\f[] required, users can double the |
|
precision (\f[B]scale\f[]) and then truncate. |
|
.PP |
|
The transcendental functions in the standard math library are: |
|
.IP \[bu] 2 |
|
\f[B]s(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]c(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]a(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]l(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]e(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]j(x, n)\f[] |
|
.PP |
|
The transcendental functions in the extended math library are: |
|
.IP \[bu] 2 |
|
\f[B]l2(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]l10(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]log(x, b)\f[] |
|
.IP \[bu] 2 |
|
\f[B]pi(p)\f[] |
|
.IP \[bu] 2 |
|
\f[B]t(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]a2(y, x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]sin(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]cos(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]tan(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]atan(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]atan2(y, x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]r2d(x)\f[] |
|
.IP \[bu] 2 |
|
\f[B]d2r(x)\f[] |
|
.SH RESET |
|
.PP |
|
When bc(1) encounters an error or a signal that it has a non\-default |
|
handler for, it resets. |
|
This means that several things happen. |
|
.PP |
|
First, any functions that are executing are stopped and popped off the |
|
stack. |
|
The behavior is not unlike that of exceptions in programming languages. |
|
Then the execution point is set so that any code waiting to execute |
|
(after all functions returned) is skipped. |
|
.PP |
|
Thus, when bc(1) resets, it skips any remaining code waiting to be |
|
executed. |
|
Then, if it is interactive mode, and the error was not a fatal error |
|
(see the \f[B]EXIT STATUS\f[] section), it asks for more input; |
|
otherwise, it exits with the appropriate return code. |
|
.PP |
|
Note that this reset behavior is different from the GNU bc(1), which |
|
attempts to start executing the statement right after the one that |
|
caused an error. |
|
.SH PERFORMANCE |
|
.PP |
|
Most bc(1) implementations use \f[B]char\f[] types to calculate the |
|
value of \f[B]1\f[] decimal digit at a time, but that can be slow. |
|
This bc(1) does something different. |
|
.PP |
|
It uses large integers to calculate more than \f[B]1\f[] decimal digit |
|
at a time. |
|
If built in a environment where \f[B]BC_LONG_BIT\f[] (see the |
|
\f[B]LIMITS\f[] section) is \f[B]64\f[], then each integer has |
|
\f[B]9\f[] decimal digits. |
|
If built in an environment where \f[B]BC_LONG_BIT\f[] is \f[B]32\f[] |
|
then each integer has \f[B]4\f[] decimal digits. |
|
This value (the number of decimal digits per large integer) is called |
|
\f[B]BC_BASE_DIGS\f[]. |
|
.PP |
|
In addition, this bc(1) uses an even larger integer for overflow |
|
checking. |
|
This integer type depends on the value of \f[B]BC_LONG_BIT\f[], but is |
|
always at least twice as large as the integer type used to store digits. |
|
.SH LIMITS |
|
.PP |
|
The following are the limits on bc(1): |
|
.IP \[bu] 2 |
|
\f[B]BC_LONG_BIT\f[] |
|
.RS 2 |
|
.PP |
|
The number of bits in the \f[B]long\f[] type in the environment where |
|
bc(1) was built. |
|
This determines how many decimal digits can be stored in a single large |
|
integer (see the \f[B]PERFORMANCE\f[] section). |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_BASE_DIGS\f[] |
|
.RS 2 |
|
.PP |
|
The number of decimal digits per large integer (see the |
|
\f[B]PERFORMANCE\f[] section). |
|
Depends on \f[B]BC_LONG_BIT\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_BASE_POW\f[] |
|
.RS 2 |
|
.PP |
|
The max decimal number that each large integer can store (see |
|
\f[B]BC_BASE_DIGS\f[]) plus \f[B]1\f[]. |
|
Depends on \f[B]BC_BASE_DIGS\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_OVERFLOW_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The max number that the overflow type (see the \f[B]PERFORMANCE\f[] |
|
section) can hold. |
|
Depends on \f[B]BC_LONG_BIT\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_BASE_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum output base. |
|
Set at \f[B]BC_BASE_POW\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_DIM_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum size of arrays. |
|
Set at \f[B]SIZE_MAX\-1\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_SCALE_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum \f[B]scale\f[]. |
|
Set at \f[B]BC_OVERFLOW_MAX\-1\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_STRING_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum length of strings. |
|
Set at \f[B]BC_OVERFLOW_MAX\-1\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_NAME_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum length of identifiers. |
|
Set at \f[B]BC_OVERFLOW_MAX\-1\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_NUM_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum length of a number (in decimal digits), which includes |
|
digits after the decimal point. |
|
Set at \f[B]BC_OVERFLOW_MAX\-1\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_RAND_MAX\f[] |
|
.RS 2 |
|
.PP |
|
The maximum integer (inclusive) returned by the \f[B]rand()\f[] operand. |
|
Set at \f[B]2^BC_LONG_BIT\-1\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
Exponent |
|
.RS 2 |
|
.PP |
|
The maximum allowable exponent (positive or negative). |
|
Set at \f[B]BC_OVERFLOW_MAX\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
Number of vars |
|
.RS 2 |
|
.PP |
|
The maximum number of vars/arrays. |
|
Set at \f[B]SIZE_MAX\-1\f[]. |
|
.RE |
|
.PP |
|
Actual values can be queried with the \f[B]limits\f[] statement. |
|
.PP |
|
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 ENVIRONMENT VARIABLES |
|
.PP |
|
bc(1) recognizes the following environment variables: |
|
.IP \[bu] 2 |
|
\f[B]POSIXLY_CORRECT\f[] |
|
.RS 2 |
|
.PP |
|
If this variable exists (no matter the contents), bc(1) behaves as if |
|
the \f[B]\-s\f[] option was given. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_ENV_ARGS\f[] |
|
.RS 2 |
|
.PP |
|
This is another way to give command\-line arguments to bc(1). |
|
They should be in the same format as all other command\-line arguments. |
|
These are always processed first, so any files given in |
|
\f[B]BC_ENV_ARGS\f[] will be processed before arguments and files given |
|
on the command\-line. |
|
This gives the user the ability to set up "standard" options and files |
|
to be used at every invocation. |
|
The most useful thing for such files to contain would be useful |
|
functions that the user might want every time bc(1) runs. |
|
.PP |
|
The code that parses \f[B]BC_ENV_ARGS\f[] will correctly handle quoted |
|
arguments, but it does not understand escape sequences. |
|
For example, the string \f[B]"/home/gavin/some bc file.bc"\f[] will be |
|
correctly parsed, but the string \f[B]"/home/gavin/some "bc" |
|
file.bc"\f[] will include the backslashes. |
|
.PP |
|
The quote parsing will handle either kind of quotes, \f[B]\[aq]\f[] or |
|
\f[B]"\f[]. |
|
Thus, if you have a file with any number of single quotes in the name, |
|
you can use double quotes as the outside quotes, as in \f[B]"some |
|
\[aq]bc\[aq] file.bc"\f[], and vice versa if you have a file with double |
|
quotes. |
|
However, handling a file with both kinds of quotes in |
|
\f[B]BC_ENV_ARGS\f[] is not supported due to the complexity of the |
|
parsing, though such files are still supported on the command\-line |
|
where the parsing is done by the shell. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_LINE_LENGTH\f[] |
|
.RS 2 |
|
.PP |
|
If this environment variable exists and contains an integer that is |
|
greater than \f[B]1\f[] and is less than \f[B]UINT16_MAX\f[] |
|
(\f[B]2^16\-1\f[]), bc(1) will output lines to that length, including |
|
the backslash (\f[B]\\\f[]). |
|
The default line length is \f[B]70\f[]. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]BC_EXPR_EXIT\f[] |
|
.RS 2 |
|
.PP |
|
If this variable exists (no matter the contents), bc(1) will exit |
|
immediately after executing expressions and files given by the |
|
\f[B]\-e\f[] and/or \f[B]\-f\f[] command\-line options (and any |
|
equivalents). |
|
.RE |
|
.SH EXIT STATUS |
|
.PP |
|
bc(1) returns the following exit statuses: |
|
.IP \[bu] 2 |
|
\f[B]0\f[] |
|
.RS 2 |
|
.PP |
|
No error. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]1\f[] |
|
.RS 2 |
|
.PP |
|
A math error occurred. |
|
This follows standard practice of using \f[B]1\f[] for expected errors, |
|
since math errors will happen in the process of normal execution. |
|
.PP |
|
Math errors include divide by \f[B]0\f[], taking the square root of a |
|
negative number, using a negative number as a bound for the |
|
pseudo\-random number generator, attempting to convert a negative number |
|
to a hardware integer, overflow when converting a number to a hardware |
|
integer, and attempting to use a non\-integer where an integer is |
|
required. |
|
.PP |
|
Converting to a hardware integer happens for the second operand of the |
|
power (\f[B]^\f[]), places (\f[B]\@\f[]), left shift (\f[B]<<\f[]), and |
|
right shift (\f[B]>>\f[]) operators and their corresponding assignment |
|
operators. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]2\f[] |
|
.RS 2 |
|
.PP |
|
A parse error occurred. |
|
.PP |
|
Parse errors include unexpected \f[B]EOF\f[], using an invalid |
|
character, failing to find the end of a string or comment, using a token |
|
where it is invalid, giving an invalid expression, giving an invalid |
|
print statement, giving an invalid function definition, attempting to |
|
assign to an expression that is not a named expression (see the |
|
\f[I]Named Expressions\f[] subsection of the \f[B]SYNTAX\f[] section), |
|
giving an invalid \f[B]auto\f[] list, having a duplicate |
|
\f[B]auto\f[]/function parameter, failing to find the end of a code |
|
block, attempting to return a value from a \f[B]void\f[] function, |
|
attempting to use a variable as a reference, and using any extensions |
|
when the option \f[B]\-s\f[] or any equivalents were given. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]3\f[] |
|
.RS 2 |
|
.PP |
|
A runtime error occurred. |
|
.PP |
|
Runtime errors include assigning an invalid number to \f[B]ibase\f[], |
|
\f[B]obase\f[], or \f[B]scale\f[]; give a bad expression to a |
|
\f[B]read()\f[] call, calling \f[B]read()\f[] inside of a |
|
\f[B]read()\f[] call, type errors, passing the wrong number of arguments |
|
to functions, attempting to call an undefined function, and attempting |
|
to use a \f[B]void\f[] function call as a value in an expression. |
|
.RE |
|
.IP \[bu] 2 |
|
\f[B]4\f[] |
|
.RS 2 |
|
.PP |
|
A fatal error occurred. |
|
.PP |
|
Fatal errors include memory allocation errors, I/O errors, failing to |
|
open files, attempting to use files that do not have only ASCII |
|
characters (bc(1) only accepts ASCII characters), attempting to open a |
|
directory as a file, and giving invalid command\-line options. |
|
.RE |
|
.PP |
|
The exit status \f[B]4\f[] is special; when a fatal error occurs, bc(1) |
|
always exits and returns \f[B]4\f[], no matter what mode bc(1) is in. |
|
.PP |
|
The other statuses will only be returned when bc(1) is not in |
|
interactive mode (see the \f[B]INTERACTIVE MODE\f[] section), since |
|
bc(1) resets its state (see the \f[B]RESET\f[] section) and accepts more |
|
input when one of those errors occurs in interactive mode. |
|
This is also the case when interactive mode is forced by the |
|
\f[B]\-i\f[] flag or \f[B]\-\-interactive\f[] option. |
|
.PP |
|
These exit statuses allow bc(1) to be used in shell scripting with error |
|
checking, and its normal behavior can be forced by using the |
|
\f[B]\-i\f[] flag or \f[B]\-\-interactive\f[] option. |
|
.SH INTERACTIVE MODE |
|
.PP |
|
Per the |
|
standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html), |
|
bc(1) has an interactive mode and a non\-interactive mode. |
|
Interactive mode is turned on automatically when both \f[B]stdin\f[] and |
|
\f[B]stdout\f[] are hooked to a terminal, but the \f[B]\-i\f[] flag and |
|
\f[B]\-\-interactive\f[] option can turn it on in other cases. |
|
.PP |
|
In interactive mode, bc(1) attempts to recover from errors (see the |
|
\f[B]RESET\f[] section), and in normal execution, flushes |
|
\f[B]stdout\f[] as soon as execution is done for the current input. |
|
.SH TTY MODE |
|
.PP |
|
If \f[B]stdin\f[], \f[B]stdout\f[], and \f[B]stderr\f[] are all |
|
connected to a TTY, bc(1) turns on "TTY mode." |
|
.PP |
|
TTY mode is required for history to be enabled (see the \f[B]COMMAND |
|
LINE HISTORY\f[] section). |
|
It is also required to enable special handling for \f[B]SIGINT\f[] |
|
signals. |
|
.PP |
|
The prompt is enabled in TTY mode. |
|
.PP |
|
TTY mode is different from interactive mode because interactive mode is |
|
required in the bc(1) |
|
specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html), |
|
and interactive mode requires only \f[B]stdin\f[] and \f[B]stdout\f[] to |
|
be connected to a terminal. |
|
.SH SIGNAL HANDLING |
|
.PP |
|
Sending a \f[B]SIGINT\f[] will cause bc(1) to stop execution of the |
|
current input. |
|
If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[] section), it will |
|
reset (see the \f[B]RESET\f[] section). |
|
Otherwise, it will clean up and exit. |
|
.PP |
|
Note that "current input" can mean one of two things. |
|
If bc(1) is processing input from \f[B]stdin\f[] in TTY mode, it will |
|
ask for more input. |
|
If bc(1) is processing input from a file in TTY mode, it will stop |
|
processing the file and start processing the next file, if one exists, |
|
or ask for input from \f[B]stdin\f[] if no other file exists. |
|
.PP |
|
This means that if a \f[B]SIGINT\f[] is sent to bc(1) as it is executing |
|
a file, it can seem as though bc(1) did not respond to the signal since |
|
it will immediately start executing the next file. |
|
This is by design; most files that users execute when interacting with |
|
bc(1) have function definitions, which are quick to parse. |
|
If a file takes a long time to execute, there may be a bug in that file. |
|
The rest of the files could still be executed without problem, allowing |
|
the user to continue. |
|
.PP |
|
\f[B]SIGTERM\f[] and \f[B]SIGQUIT\f[] cause bc(1) to clean up and exit, |
|
and it uses the default handler for all other signals. |
|
The one exception is \f[B]SIGHUP\f[]; in that case, when bc(1) is in TTY |
|
mode, a \f[B]SIGHUP\f[] will cause bc(1) to clean up and exit. |
|
.SH COMMAND LINE HISTORY |
|
.PP |
|
bc(1) supports interactive command\-line editing. |
|
If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[] section), history is |
|
enabled. |
|
Previous lines can be recalled and edited with the arrow keys. |
|
.PP |
|
\f[B]Note\f[]: tabs are converted to 8 spaces. |
|
.SH LOCALES |
|
.PP |
|
This bc(1) ships with support for adding error messages for different |
|
locales and thus, supports \f[B]LC_MESSAGES\f[]. |
|
.SH SEE ALSO |
|
.PP |
|
dc(1) |
|
.SH STANDARDS |
|
.PP |
|
bc(1) is compliant with the IEEE Std 1003.1\-2017 |
|
(“POSIX.1\-2017”) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) |
|
specification. |
|
The flags \f[B]\-efghiqsvVw\f[], all long options, and the extensions |
|
noted above are extensions to that specification. |
|
.PP |
|
Note that the specification explicitly says that bc(1) only accepts |
|
numbers that use a period (\f[B].\f[]) as a radix point, regardless of |
|
the value of \f[B]LC_NUMERIC\f[]. |
|
.PP |
|
This bc(1) supports error messages for different locales, and thus, it |
|
supports \f[B]LC_MESSAGES\f[]. |
|
.SH BUGS |
|
.PP |
|
None are known. |
|
Report bugs at https://git.yzena.com/gavin/bc. |
|
.SH AUTHORS |
|
.PP |
|
Gavin D. |
|
Howard <yzena.tech@gmail.com> and contributors.
|
|
|