Provides an interpreter for arbitrary-precision arithmetic language.

The bc command is an interactive process that provides arbitrary-precision arithmetic. The bc command first reads any input files specified by the File parameter and then reads the standard input. The input files must be text files containing a sequence of commands, statements, or function definitions that the bc command can read and execute.

The bc command is a preprocessor for the dc command. It calls the dc command automatically, unless the -c (compile only) flag is specified. If the -c flag is specified, the output from the bc command goes to standard output.

The bc command allows you to specify an input and output base for operations in decimal, octal, or hexadecimal. The default is decimal. The command also has a scaling provision for decimal point notation. The bc command always uses the . (period) to represent the radix point, regardless of any decimal point character specified as part of the current locale.

The syntax for the bc command is similar to that of the C language. You can use the bc command to translate between bases by assigning the ibase keyword to the input base and the obase keyword to the output base. A range of 2-16 is valid for the ibase keyword. The obase keyword ranges from 2 up to the limit set by the BC_BASE_MAX value defined in the /usr/include/sys/limits.h file. Regardless of the ibase and obase settings, the bc command recognizes the letters A-F as their hexadecimal values 10-15.

The output of the bc command is controlled by the program read. Output consists of one or more lines containing the value of all executed expressions without assignments. The radix and precision of the output are controlled by the values of the obase and scale keywords.

Further information about the way in which the bc command processes information from a source file is described in the following sections:

- Grammar
- Lexical Conventions
- Identifiers and Operators
- Expressions
- Statements
- Function Calls
- Functions in -I Math Library

The following grammer describes the syntax for the bc program, where `program` stands
for any valid program:

%token EOF NEWLINE STRING LETTER NUMBER

%token MUL_OP /* '*', '/', '%' */

%token ASSIGN_OP /* '=', '+=', '-=', '*=', '/=', '%=', '^=' */

%token REL_OP /* '==', '<=', '>=', '!=', '<', '>' */

%token INCR_DECR /* '++', '--' */

%token Define Break Quit Length /* 'define', 'break', 'quit', 'length' */

%token Return For If While Sqrt /* 'return', 'for', 'if', 'while', 'sqrt' */

%token Scale Ibase Obase Auto /* 'scale', 'ibase', 'obase', 'auto' */

%start program

%%

program : EOF | input_item program ;

input_item : semicolon_list NEWLINE | function ;

semicolon_list : /* empty */ | statement | semicolon_list ';' statement | semicolon_list ';' ;

statement_list : /* empty */ | statement | statement_list NEWLINE | statement_list NEWLINE statement | statement_list ';' | statement_list ';' statement ;

statement : expression | STRING | Break | Quit | Return | Return '(' return_expression ')' | For '(' expression ';' relational_expression ';' expression ')' statement | If '(' relational_expression ')' statement | While '(' relational_expression ')' statement | '{' statement_list '}' ;

function : Define LETTER '(' opt_parameter_list ')' '{' NEWLINE opt_auto_define_list statement_list '}' ;

opt_parameter_list:/* empty */ | parameter_list ;

parameter_list : LETTER | define_list ',' LETTER ;

opt_auto_define_list : /* empty */ | Auto define_list NEWLINE | Auto define_list ';' ;

define_list : LETTER | LETTER '[' ']' | define_list ',' LETTER | define_list ',' LETTER '[' ']' ;

opt_argument_list : /* empty */ | argument_list ;

argument_list : expression | argument_list ',' expression ;

relational_expression : expression | expression REL_OP expression ;

return_expression : /* empty */ | expression ;

expression : named_expression | NUMBER | '(' expression ')' | LETTER '(' opt_argument_list ')' | '-' expression | expression '+' expression | expression '-' expression | expression MUL_OP expression | expression '^' expression | INCR_DECR named_expression | named_expression INCR_DECR | named_expression ASSIGN_OP expression | Length '(' expression ')' | Sqrt '(' expression ')' | Scale '(' expression ')' ;

named_expression : LETTER | LETTER '[' expression ']' | Scale | Ibase | Obase ;

The following lexical conventions apply to the bc command:

- The bc command recognizes the longest possible lexical token or delimiter beginning at a given point.
- Comments begin with /* (slash, asterisk) and end with */ (asterisk, slash). Comments have no effect except to delimit lexical tokens.
- The newline character is recognized as the NEWLINE token.
- The STRING token represents a string constant. The string begins with " (double quotation mark) and terminates with " (double quotation mark). All characters between the quotation marks are taken literally. There is no way to specify a string that contains " (double quotation mark). The length of each string is limited to the maximum bytes set in the BC_STRING_MAX value, which is defined in the limits.h file.
- Blank characters have no effect except as they appear in the STRING token or when used to delimit lexical tokens.
- The \n (backslash, newline) character:
- A NUMBER token uses
the following grammar:
NUMBER : integer | '.' integer | integer '.' |integer '.' integer ; integer : digit | integer digit ; digit : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F ;

NUMBER token values are interpreted as numerals in the base specified by the ibase internal register value.

- The value of a NUMBER token is interpreted as a numeral in the base specified by the value of the ibase internal register. Each of the digit characters has the value from 0 to 15 in the order listed here, and the period character presents the radix point. The behavior is undefined if digits greater than or equal to the value of the ibase register appear in the token. There is an exception for single-digit values being assigned to the ibase and obase registers themselves.
- The following keywords are recognized as
tokens:
auto for length return sqrt break ibase obase scale while define if quit

- Except within a keyword, any of the following
letters are considered a LETTER token:
a b c d e f g h i j k l m n o p q r s t u v w x y z

- The following single-character and two-character sequences are recognized as the ASSIGN_OP token:
- The following single characters are recognized as the MUL_OP token:
- The following single-character and two-character sequences are recognized as the REL_OP token:
- The following two-character sequences are recognized as the INCR_DECR token:
- The following single characters are recognized as tokens. The token has the same name as the character:
- The EOF token is returned when the end of input is reached.

There are three kinds of identifiers recognized by the bc command: ordinary identifiers, array identifiers, and function identifiers. All three types consist of single, lowercase letters. Array identifiers are followed by [ ] (left and right brackets). An array subscript is required except in an argument or auto list. Arrays are singly dimensioned and can contain up to the amount specified by the BC_DIM_MAX value. Indexing begins at 0. Therefore an array is indexed from 0 up to the value defined by BC_DIM_MAX -1. Subscripts are truncated to integers. Function identifiers must be followed by ( ) (left and right parentheses) and possibly by enclosing arguments. The three types of identifiers do not conflict.

The Operators in a bc Program table summarizes the rules for precedence and associativity of all operators. Operators on the same line have the same precedence. Rows are in order of decreasing precedence.

Operators in a bc Program | |

Operator | Associativity |

++, - - | not applicable |

unary - | not applicable |

^ | right to left |

*, /, % | left to right |

+, binary - | left to right |

=, +=, -=, *=, /=, ^= | right to left |

==, <=, >=, !=, <, > | none |

Each expression or named expression has a scale, which is the number of decimal digits maintained as the fractional portion of the expression.

Named expressions are places where values are stored. Named expressions are valid on the left side of an assignment. The value of a named expression is the value stored in the place named. Simple identifiers and array elements are named expressions; they have an initial value of zero and an initial scale of zero.

The internal registers scale, ibase, and obase are all named expressions. The scale of an expression consisting of the name of one of these registers is 0. Values assigned to any of these registers are truncated to integers. The scale register contains a global value used in computing the scale of expressions (as described below). The value of the scale register is limited to 0 <= scale <= {BC_SCALE_MAX} and has a default value of 0. The ibase and obase registers are the input and output number radix, respectively. The value of ibase is limited to 2 <= ibase <= 16. The value of obase is limited to 2 <= obase = {BC_BASE_MAX}

When either the ibase or obase registers are assigned a single-digit value from the list described in "Lexical Conventions" , the value is assumed in hexadecimal. For example:

ibase=A

sets to base ten, regardless of the current ibase register value. Otherwise, the behavior is undefined when digits greater than or equal to the value of the ibase register appear in the input. Both ibase and obase registers have initial values of 10.

Internal computations are conducted as if in decimal, regardless of the input and output bases, to the specified number of decimal digits. When an exact result is not achieved, for example:

`scale=0; 3.2/1`

the bc command truncates the result.

All numerical values of the obase register are output according to the following rules:

- If the value is less than 0, output a - (hyphen).
- Output one of the following, depending on
the numerical value:
- If the absolute value of the numerical value is greater than or equal to 1, output the integer portion of the value as a series of digits appropriate to the obase register (described in step 3). Next output the most significant non-zero digit, followed by each successively less significant digit.
- If the absolute value of the numerical value is less than 1 but greater than 0 and the scale of the numerical value is greater than 0, it is unspecified whether the character 0 is output.
- If the numerical value is 0, output the character 0.

- If the scale of the value is greater than 0,
output a . (period) followed by a series of digits appropriate to the following obase register values. The digits represent the most significant
portion of the fractional part of the value, and s
represents the scale of the value being output:
- If the obase value is 10, output s number of digits.
- If the obase value is greater than 10, output the number less than or equal to s.
- If the obase value is less than 10, output a number greater than or equal to s.
- For obase values other than 10, this should be the number of digits needed to represent a precision of 10s.
- For obase values from
2 to 16, valid digits are the first obase of the single
characters:
0 1 2 3 4 5 6 7 8 9 A B C D E F

which represent the values 0 through 15, respectively.

- For bases greater than 16, each digit is
written as a separate multidigit decimal number. Each digit except the most
significant fractional digit is preceded by a single space character. For
bases 17 to 100, the bc command writes two-digit decimal
numbers, for bases 101 to 1000 the bc command writes
three-digit decimal numbers. For example, the decimal number 1024 in base
25 would be written as:
01 15 24

in base 125, as:

008 024

A numeric constant is an expression. The scale is the number of digits that follow the radix point in the input representing the constant, or 0 if no radix point appears.

The sequence (expression) is an expression with the same value and scale as expression. The parentheses can be used to alter the normal precedence.

The unary and binary operators have the following semantics:

The exponentiation operator, ^ (caret), binds right to left.

The multiplicative operators * (asterisk), / (slash), and % (percent) bind left to right.

The additive operators + (plus) and - (minus) bind left to right.

The following assignment operators bind right to left:

- = (equal sign)
- += (plus, equal sign)
- -= (minus, equal sign)
- *= (asterisk, equal sign)
- /= (slash, equal sign)
- %= (percent, equal sign)
- ^= (caret, equal sign)

The compound assignment forms:

named-expression <operator >= expression

are equivalent to:

named-expression = named-expression <operator > expression

except that the named expression is evaluated only once.

Unlike all other operators, the following relational operators are only valid as the object of an if or while statement or inside a for statement:

- < (less than)
- > (greater than)
- <= (less than, equal sign)
- >= (greater than, equal sign)
- == (double equal sign)
- != (exclamation, equal sign)

When a statement is an expression, unless the main operator is an assignment, execution of the statement writes the value of the expression followed by a newline character.

When a statement is a string, execution of the statement writes the value of the string.

Statements separated by semicolons or newline characters are executed sequentially. In an interactive invocation of the bc command, each time a newline character is read that satisfies the grammatical production:

input_item : semicolon_list NEWLINE

the sequential list of statements making up the semicolon_list is executed immediately, and any output produced by that execution is written without any buffer delay.

If an if statement (if (relation) statement), the statement is executed if the relation is true.

The while statement (while (relation) statement) implements a loop in which the relation is tested. Each time the relation is true, the statement is executed and the relation retested. When the relation is false, execution resumes after statement.

A for statement (for (expression; relation; expression) statement) is the same as:

first-expression while (relation) { statement last-expression }

All three expressions must be present.

The break statement causes termination for a for or while statement.

The auto statement (auto identifier [,identifier ] ...) causes the values of the identifiers to be pushed down. The identifiers can be ordinary identifiers or array identifiers. Array identifiers are specified by following the array name by empty square brackets. The auto statement must be the first statement in a function definition.

The define statement:

define LETTER ( opt_parameter_list ) { opt_auto_define_list statement_list }

defines a function named `LETTER`. If the `LETTER` function
was previously defined, the define statement replaces
the previous definition. The expression:

LETTER ( opt_argument_list )

invokes the `LETTER` function. The behavior is undefined if the number of arguments
in the invocation does not match the number of parameters in the definition.
Functions are defined before they are invoked. A function is considered defined
within its own body, so recursive calls are valid. The values of numeric constants
within a function are interpreted in the base specified by the value of the ibase register when the function is invoked.

The return statements (return and return(expression)) cause termination of a function, popping of its auto variables, and specify the result of the function. The first form is equivalent to return(0). The value and scale of an invocation of the function is the value and scale of the expression in parentheses.

The quit statement (quit) stops execution of a bc program at the point where the statement occurs in the input, even if it occurs in a function definition or in an if, for, or while statement.

A function call consists of a function name followed by parentheses containing a comma-separated list of expressions, which are the function arguments. A whole array passed as an argument is specified by the array name followed by [ ] (left and right brackets). All function arguments are passed by value. As a result, changes made to the formal parameters have no effect on the actual arguments. If the function terminates by executing a return statement, the value of the function is the value of the expression in the parentheses of the return statement, or 0 if no expression is provided or if there is no return statement.

The result of sqrt(expression) is the square root of the expression. The result is truncated in the least significant decimal place. The scale of the result is the scale of the expression or the value of scale, whichever is larger.

The result of length(expression) is the total number of significant decimal digits in the expression. The scale of the result is 0.

The result of scale(expression) is the scale of the expression. The scale of the result is 0.

There are only two storage classes in a bc program, global and automatic (local). Only identifiers that are to be local to a function need be declared with the auto keyword. The arguments to a function are local to the function. All other identifiers are assumed to be global and available to all functions. All identifiers, global and local, have initial values of 0. Identifiers declared as auto are allocated on entry to the function and released on returning from the function. Therefore they do not retain values between function calls. The auto arrays are specified by the array name followed by [ ] (left bracket, right bracket). On entry to a function, the old values of the names that appear as parameters and as automatic variables are pushed onto a stack. Until the function returns, reference to these names refers only to the new values.

References to any of these names from other functions that are called from this function also refer to the new value until one of those functions uses the same name for a local variable.

The following functions are defined when you specify the -l flag:

The scale of an invocation of each of these functions is the value of the scale keyword when the function is invoked. The behavior is undefined if any of these functions is invoked with an argument outside the domain of the mathematical function.

-c | Compiles the File parameter, but does not invoke the dc command. |

-l | (Lowercase L) Defines a library of math functions, and sets the scale variable to 20. |

This command returns the following exit values:

0 | Successful completion. |

1 | Encountered a syntax error or could not access the input file. |

unspecified | Any other error occurred. |

- You can use the bc command as a calculator.
Depending on whether you set the scale variable and
with what value, the system displays fractional amounts. Entering:
bc 1/4

displays only

`0`. To set the scale variable and add a comment, enter:scale = 1 /* Keep 1 decimal place */ 1/4

The screen displays

`0.2`. Entering:scale = 3 /* Keep 3 decimal places */ 1/4

displays

`0.250`. Entering:16+63/5

displays

`28.600`. Entering(16+63)/5

displays

`15.800`. Entering71/6

displays

`11.833`.The bc command displays the value of each expression when you press the Enter key, except for assignments.

When you enter the bc command expressions directly from the keyboard, press the End-of-File (Ctrl-D) key sequence to end the bc command session and return to the shell command line.

- To write and run a C-like program, enter a command similar
to the following:

`bc -l prog.bc`

e(2) /* e squared */

ma

The screen displays`7.38905609893065022723`. If you enter:f(5) /* 5 factorial */

The screen displays

`120`. If you enter:f(10) /* 10 factorial */

The screen displays

`3628800`.This sequence interprets the bc program saved in the prog.bc file, and reads more of the bc command statements from the keyboard. Starting the bc command with the -l flag makes the math library available. This example uses the e (exponential) function from the math library, and

`f`is defined in the prog.bc program file as:/* compute the factorial of n */ define f(n) { auto i, r; r = 1; for (i=2; i<=n; i++) r =* i; return (r); }

The statement following a for or while statement must begin on the same line. When you enter the bc command expressions directly from the keyboard, press the End-of-File (Ctrl-D) key sequence to end the bc command session and return to the shell command line.

- To convert an infix expression to Reverse Polish Notation
(RPN), enter:

`bc -c`

(a * b) % (3 + 4 * c)

The screen displays:lalb* 3 4lc*+%ps.

This sequence compiles the bc command infix-notation expression into an expression that the dc command can interpret. The dc command evaluates extended RPN expressions. In the compiled output, the

`l`before each variable name is the dc subcommand to load the value of the variable onto the stack. The`p`displays the value on top of the stack, and the`s.`discards the top value by storing it in register`.`(dot). You can save the RPN expression in a file for the dc command to evaluate later by redirecting the standard output of this command. When you enter the bc command expressions directly from the keyboard, press the End-of-File (Ctrl-D) key sequence to end the bc command session and return to the shell command line. - To assign in the shell an approximation of the first
10 digits of pi to the variable x, enter:
x=$(printf "%s\n" 'scale = 10; 104348/33215' | bc)

The following bc program prints the same approximation of pi, with a label, to standard output:

scale = 10 "pi equals " 104348 / 33215

- To define a function to compute an approximate value
of the exponential function (such a function is predefined if the -l (lowercase
L) option is specified), enter:
scale = 20 define e(x){ auto a, b, c, i, s a = 1 b = 1 s = 1 for (i = 1; 1 == 1; i++){ a = a*x b = b*i c = a/b if (c == 0) { return(s) } s = s+c } }

To print approximate values of the exponential function of the first 10 integers, enter:

for (i = 1; i <= 10; ++i) { e(i) }

/usr/bin/bc | Contains the bc command. |

/usr/lib/lib.b | Contains the mathematical library. |

/usr/bin/dc | Contains the desk calculator. |