# bc

## arbitrary precision calculator

` bc [ -lwsqv ] [long-options] [ file … ]`

Supports arbitrary precision numbers.
Executes `files` on the command line, then reads from the standard input and processes interactively.

 `--mathlib -l ` Sets `scale=20` loads math library. `--warn -w ` Give warnings for extensions to POSIX bc. `--standard-s ` POSIX `--quiet -q ` Do not print the welcome. `--version -v` Display version number, short copyright and quit. see warranty.```bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. ```

Suggestion: In `.profile` set up alias bc='/usr/bin/bc -q ~/.bin/bc.ini' and
create `~/.bin/bc.ini` containing :scale=2
then `echo 5/6|bc` will output `.83`

• NUMBERS are arbitrary precision in both the integer and the fractional parts,
are represented internally in decimal , all computations are done in decimal.
Attributes :
1. `length`: number of significant digits
2. `scale `: number of digits after the dot. Default:!
For example:
`1.23456` has a length of 6 and scale of 5.
`1234.567` has a length of 7 and a scale of 3.
3. Input digits: -`9`,`A`-`F`. (NOT lowercase, which are variables).
4. Single digit numbers are the same regardless of the value of `ibase`. (i.e. `A` = 10̸.)
5. Multi-digit numbers, with digits greater or equal to `ibase`, are assigned the value of `ibase`-1 to each digit,
if `ibase`=10̸, `num=FF8CB` assigns `99899` to num.
6. There is only one type of number.

• VARIABLES
Are set to zero upon first reference, names begin with a lowercase letter followed by letters, digits and underscores POSIX names are a single lower case letter.
1. Simple: `a, f, x1, y, index23`, `loop_counter`, `x`
2. Arrays: variable name followed by brackets `[ ]`.
3. Special variables:
• `scale` defines how some operations use digits after the dot. Default .
Expressions have a scale derived from: the value of `scale`, the numbers and the operation performed.
The result has the `scale` of the maximum scale of the expressions involved, unless specifically mentioned.
Example:
```scale=2
a=1.234
a
1.234 ```
1.234 in the asignment has a scale of 3 so result has scale of 3.

• `last` has the value of the last number output. Some implementations also permit using dot (`.`) (extension)
• `history` size of readline history, -1 max, (not retained across sesssions.)
• `ibase` and `obase` base for input and output. Default base 10, maximun `ibase` 16.
`obase=F+1` always sets `obase` to 16 (i.e. hexadecimal)
`ibase=A` always sets `ibase` to 10.
If `ibase` is 16, `ibase=10`16 keeps `ibase` to 16 !
If `ibase` is  2, `ibase=10`2 keeps `ibase` to 2 !
`obase` is not synchronized with `ibase`, Example: `obase=2;binary=9;binary` displays `1001` !

For `obase`s greater than 16, a multi-digit, base 10 format is used.

```ibase=F+1
obase=A
FFFF
65535

obase=64
FFFF
06 55 35

ibase=A
99
01 35  1*6410 + 3510
64*64
01 00 00   1*64*6410  ```

`/*` and `*/` surround a comment, may start anywhere, appear as a single space in the input, delimit other input items, can be multi-line
`#` begins a comment which continues to the end of line.

• EXPRESSIONS and STATEMENTS
Executed when end-of-line is encountered.

 `- expr` negation of `expr`. `++var` incremented by one, the new value is the result of the expression. `--var` decremented by one, the new value is the result of the expression. `var++` The result of the expression is the value of `var`, then `var` is incremented by one. `var-- ` The result of the expression is the value of `var`, then `var` is decremented by one. `expr + expr` sum `expr - expr` difference `expr * expr` product ` expr / expr` divide. The scale of the result is `scale`! ` expr1 % expr2` remainder computed by: expr1/expr2 is computed to scale digits. That result is used to compute `expr1-(expr1/expr2)*expr2` to the scale of the maximum of `scale+scale(expr2)` and `scale(expr1)` If `scale` is zero and both expressions are integers this is the integer remainder `exprn ^ Iexprx` `exprn` raised to the integer `Iexprx`. If the exponent is negative: the scale of the result is `scale` . If the exponent is positive the scale of the result is the minimum of the scale of the first expression times the value of the exponent and the maximum of `scale` and the scale of the first expression. (example:.` scale(a^b) = min(scale(a)*b, max( scale, scale(a)))`.) `exprn^0` returns 1 `( expr )` alters precedence `var = expr` assignment ` var op= expr` example: sum `+=` entry equivalent to "`var = var op expr`" . `var` is evaluated only once. This can make a difference if `var` is an array.

Relational expressions may appear in an expression.
(POSIX bc requires that relational expressions are used only in if, while, and for statements and that only one relational test may be done in them.)

 Relational operators result is 1 (true) if `expr1 < expr2` expr1 is strictly less than expr2. `expr1 <= expr2` expr1 is less than or equal to expr2. `expr1 > expr2` expr1 is strictly greater than expr2. `expr1 >= expr2` expr1 is greater than or equal to expr2. `expr1 == expr2` expr1 is equal to expr2. `expr1 != expr2` expr1 is not equal to expr2. Boolean operators (POSIX bc does NOT have boolean operations). `!expr ` 1 if `expr` equals 0; 0 if `expr` is non-zero `expr && expr ` both `expr1` and `expr2` are non-zero. `expr1 || expr2 ` either `expr1` or `expr2` is non-zero.

Expression precedence (highest to lowest)

 `++ -- ` nonassociative Using relational and logical operators with assignment expressions evaluate differently than in many other languages. Consider the expression: a = 3 < 5 This assigns the value 3 to `a` and then compares 3 to 5 which outputs 1. Most programmers expect the result of "3 < 5" (the value 1 (true)) is assigned to `a`. Use parenthesis when using relational and logical operators with the assignment operators. `-† ` nonassociative `^ ` right associative `* / ` `%` left associative `+ ` ` - ` left associative `= += -= `…† right associative ‡ `< <= > ` …† left associative ‡ `! ` nonassociative `&& ` left associative `|| ` left associative
The bitwise (and, or, xor , shift) , boolean and conditional operators:
```&     |     ^     &&    ||  <<    >>
&=    |=    ^=    &&=   ||= <<=   >>=
?:```
Are not available. Use easyOnLineConverter.com

• FUNCTIONS

appear as "name(parameters)".

 `read ( )` read a value from standard input . `length ( expression )` number of significant digits . `scale ( expression )` number of digits after the dot (same as special variable `scale`). ```scale=5 1/2 .50000 scale(1/2) 5 scale(1/3) 5 scale(.5) 1 ``` `sqrt ( expression )` square root. If the `expression` is negative, a run time error is generated. Runtime error (func=(main), adr=4): Square root of a negative number

User defined functions provide a method of defining a computation that can be executed later which return a value to the caller.

A function definition :
define name ( [parameter[, …] ] ) { ␤
[ auto name [ , … ]] ; statement_list }

A function call:
name(parameters).

Parameters can be numbers or arrays. Numbers are call_by value (i.e. cannot be changed within the function).
Arrays are only call_by variable. Arrays are specified in the parameter definition by the notation `name[]`.
In the function call, parameters are full expressions for number parameters. The same notation is used for passing arrays as for defining array parameters. The named array is passed by variable to the function.

Variables are global (i.e. function B can access variables in the main as well as in function A) unless included in `auto` list.
Auto variables have their current values pushed onto a stack at the start of the function, initialized to zero and used throughout the execution of the function. At function exit, these variables are popped so that the original value (at the time of the function call) of these variables are restored.
( The parameters are auto variables that are initialized to a value provided in the function call.)
Auto variables are sub-call accessable, i.e. if function A calls function B, B may access function A's auto variables, unless function B has declared them auto variables.

Constants in the function body will be converted using the value of `ibase` at the time of the call.
Changes to `ibase` will be ignored during the execution of the function except for `read()`, which will uses the current value of `ibase` for conversion of numbers.

Function definitions are "dynamic" i.e. a function is undefined until a definition is encountered (aka no forward referencing).
That definition is used until another definition function for `name` is encountered.

• STATEMENTS
Execution ocurs when a newline is encountered with one or more complete statements.
Semicolon and a newline are statement separators. A trailing `\` continutes a statment.

 ` expression` If the expression starts with `variable assignment` it is an assignment statement. If the expression is not an assignment statement, the expression is evaluated and output followed by ␤. For example  `a=1` is an assignment statement (no output is produced). `(a=1)` is an expression that has an embedded assignment and the result is output. All numbers are output in the base specified by `obase` which can range from 2 through `BC_BASE_MAX.` Some numbers may not be outputable on a single output line and will be split with `\`. Outputing a number assigns the value the the special variable `last` Some implementations permit dot (`.`) (which is not part of a number) for `last`. `"string" ` `string` is output. No newline is appended. `print list` `list` is a list of strings and expressions separated by commas. No newline is appended. Expressions are evaluated, their value is printed and assigned to `last`. Strings may contain: `\a` (alert or bell), `\b` (backspace), `\f` (form feed), `\n` (newline), `\r` (carriage return), `\q` (quotes, i.e. `"`), `\t` (tab), and `\\` (backslash). `{ statement_list } ` A compound statement, allows multiple statements to be grouped together. ```if ( expression ) statement1 [else statement2] ``` Evaluates ` expression` and if `expression ` is non-zero, `statement1` is executed. if ` expression` is 0, then `statement2 `is executed. `while ( expression ) statement` execute `statement` while `expression` is non-zero. It evaluates `expression` before each execution of `statement.` Termination of the loop is caused by a zero `expression` value or the execution of a `break` ```for ( [expression1] ; [expression2] ; [expression3] ) statement``` Controls repeated execution of `statement.` `expression1` is evaluated before the loop. `expression2` is evaluated before each execution of ` statement,` if non-zero, `statement` is evaluated. If it is zero, the loop is terminated. After each execution of ` statement`, `expression3` is evaluated before the reevaluation of `expression2.` If `expression1` or `expression3` are missing, nothing is evaluated at the point they would be evaluated. If `expression2` is missing, it is the same as substituting the value 1 for `expression2`. (POSIX bc requires all three expressions.) `break ` exits the most recent enclosing `while` or `for` . `continue` causes the most recent enclosing `for` to start the next iteration. `halt ` causes bc to `quit` Note: `if (0 == 1) halt` will not cause bc to terminate because the halt is not executed. `return ( expression )` Return the value of the expression from a function, default `0̸`. PSEUDO STATEMENTS `limits` display limits of the local version . an extension. ```BC_BASE_MAX = 2147483647 BC_DIM_MAX = 65535 BC_SCALE_MAX = 2147483647 BC_STRING_MAX = 2147483647 MAX Exponent = 9223372036854775807 Number of vars = 32767``` `quit ` `warranty` outputs version and a long non-warranty notice.

Due to the fact that auto variables and parameters are pushed onto a stack, bc supports recursive functions.

• MATH LIBRARY
If bc is invoked with `--mathlib`, a math library is loaded and the default `scale` is set to 20.

`s (r)` sine of r, r is in radians.
`c (r)` cosine of r, r is in radians.
`a (x)` arctangent of x, arctangent returns radians.
`l (x)` natural logarithm of x.
`e (x)` exponential function of raising e to the value x.
`j (n,x)` bessel function of integer order n of x.

• EXAMPLES
In /bin/sh, the following will assign the value of "pi" to the shell variable `\$pi` using acrtan of 1.

```pi=\$(echo "4*a(1)" | /usr/bin/bc -l)  # i.e. arcTan(1 radian)   π/4
echo \$pi
3.14159265358979323844```

The exponential function used in the math library, written in POSIX bc.

```              scale = 20
/* Uses the fact that e^x = (e^(x/2))^2
When x is small enough, we use the series:
e^x = 1 + x + x^2/2! + x^3/3! + ...
*/          define e(x) {
auto  a, d, e, f, i, m, v, z
/* Check the sign of x. */
if (x<0) {
m = 1
x = -x
}
/* Precondition x. */
z = scale;
scale = 4 + z + .44*x;
while (x > 1) {
f += 1;
x /= 2;
}

/* Initialize the variables. */
v = 1+x
a = x
d = 1

for (i=2; 1; i++) {
e = (a *= x) / (d *= i)
if (e == 0) {
if (f>0) while (f--)  v = v*v;
scale = z
if (m) return (1/v);
return (v/1);
}
v += e
}
}
```

Use extended features to implement a simple program for calculating checkbook balances.
This program is best kept in a file so that it can be used many times without having to retype it at every use.
```              scale=2
print "\nCheck book program!\n"
print "  Remember, deposits are negative transactions.\n"
print "  Exit by a 0 transaction.\n\n"

print "Initial balance? "; bal = read()
bal /= 1
print "\n"
while (1) {
"current balance = "; bal
if (trans == 0) break;
bal -= trans
bal /= 1
}
quit
```
Definition of the recursive factorial function.
```              define f (x) {
if (x <= 1) return (1);
return (f(x-1) * x);
}

a=(1/3)^-1
scale=4
a
3.0003
scale=5
a
3.00003
```
bc can be compiled with readline input editor library. Allows for a history of previous lines typed recallable, editable and searchable.
The special variable, `history` is the number of lines of history retained. The default, -1 unlimited, 0 disables the history.

Differences & extensions

There exists GNU bc, man , brew install although it does not seem to have any(much) additional functionallity.

 A single process which parses and runs a byte code translation of the program. `-c ` outputs the byte code, for debugging the parser and preparing the math library. `LANG` not conform POSIX processing of the LANG environment variable and all environment variables starting with `LC_`. names Traditional and POSIX bc have single letter names for functions, variables and arrays. They have been extended to be multi-character names that start with a letter and may contain letters, numbers and the underscore character. Strings Strings are not allowed to contain NUL characters. POSIX: all characters must be included in strings. `last` POSIX bc does not have a `last` variable. Some implementations use the period (.) . comparisons POSIX allows comparisons only in the `if` and `while` statements, and the second expression of the `for` statement. Only one relational operation is allowed in each of those statements. if statement, else clause POSIX bc does not have an else clause. for statement POSIX bc requires all expressions to be present in the for statement. `&&, ||, !` POSIX bc does not have logical operators. , read function, print or continue statement array parameters POSIX bc does not (currently) support array parameters in full. The POSIX grammar allows for arrays in function definitions, but does not provide a method to specify an array as a parameter. Traditional implementations of bc have only call by value array parameters. =+, =-, =*, =/, =%, =^ POSIX bc does not require these "old style" assignment operators to be defined. This version may allow these "old style" assignments. Use the limits statement to see if the installed version supports them. If it does support the "old style" assignment operators, the statement "a =- 1" will decrement a by 1 instead of setting a to the value -1. spaces in numbers Not allowed. In some implementations, "x=1 3" assigns 13 to x. errors and execution The code will be executed when syntax and other errors are found in the program. If a syntax error is found in a function definition, error recovery tries to find the beginning of a statement and continue to parse the function. Once a syntax error is found in the function, the function will not be callable and becomes undefined. Syntax errors in the interactive execution code will invalidate the current execution block. The execution block is terminated by an end of line that appears after a complete sequence of statements. For example, ```a = 1 b = 2``` has two execution blocks and ```{ a = 1 b = 2 }``` has one execution block. Any runtime error will terminate the execution of the current execution block. A runtime warning will not terminate the current execution block.

#### Interrupts

During an interactive session, the SIGINT signal (usually generated by the control-C character from the terminal) will cause execution of the current execution block to be interrupted. It will display a "runtime" error indicating which function was interrupted. After all runtime structures have been cleaned up, a message will be printed to notify the user that bc is ready for more input. All previously defined functions remain defined and the value of all non-auto variables are the value at the point of interruption. All auto variables and function parameters are removed during the clean up process.
During a non interactive session, SIGINT terminates .

### LIMITS

`limits` statment:
```BC_BASE_MAX     = 2147483647  0x7FFFFFF
BC_DIM_MAX      = 65535
BC_SCALE_MAX    = 2147483647
BC_STRING_MAX   = 2147483647
MAX Exponent    = 9223372036854775807
Number of vars  = 32767```
 `BC_BASE_MAX` maximum output base is currently set at 999. The maximum input base is 16. `BC_DIM_MAX` arbitrary limit of 65535 as distributed. `BC_SCALE_MAX` number of digits after the dot is limited to `INT_MAX` digits. The number of digits before the dot is limited to INT_MAX digits. `BC_STRING_MAX` limit on the number of characters in a string is INT_MAX characters. `exponent` value of the exponent in the raise operation (^) is limited to LONG_MAX. `multiply` multiply routine may yield incorrect results if a number has more than LONG_MAX / 90 total digits. For 32 bit longs, this number is 23,860,929 digits. `code size` Each function and the "main" program are limited to 16384 bytes of compiled byte code each. BC_MAX_SEGS can be changed to have more than 16 segments of 1024 bytes. `variable names` unique names for each of simple variables, arrays and functions.

### ENVIRONMENT VARIABLES

 `\$POSIXLY_CORRECT` same as `-s` `\$BC_ENV_ARGS` Format is the same as the command line arguments, processed first, so any files listed in the environent arguments are processed before any command line argument files. This allows the user to set up "standard" options and files to be processed at every invocation. Files in the environment variables typically contain frequently used, custom function definitions. `BC_LINE_LENGTH` Length of an output line for numbers. includes the backslash and new line characters for long numbers.

### Files

Standard math library is usually from the file `/usr/local/lib/libmath.b.` may be `/lib/libmath.b.`)
This documents GNU bc version 1.04. , by Philip A. Nelson phil@cs.wwu.edu
The author would like to thank Steve Sommars (Steve.Sommars@att.com) for his extensive help in testing the implementation. Many great suggestions were given. This is a much better product due to his involvement.