bc is an interactive processor for a language that
resembles C. It provides unlimited precision
arithmetic and displays the results within a configurable number
of decimal places, to a maximum of 99. It takes input from any
files given, then reads the standard input.
bc understands the following command line options:
-c -d
Generate commands suitable for
dc(C)
on the standard output; do not send them to dc. These
options are intended as a tool for debugging. The -c and
-d options are equivalent.
-l
Load the arbitrary precision math library.
bc acts as a preprocessor for dc, a calculator
which operates on Reverse Polish Notation input. (bc is
easier to use than dc.) Although substantial programs can
be written with bc, it is often used as an interactive
tool for performing calculator-like computations. The language
supports a complete set of control structures and functions that can
be defined and saved for later execution. The syntax of bc
has been deliberately selected to agree with the C
language. A small collection of library functions is also available,
including sin, cos, arctan, log, exponential, and Bessel functions
of integer order.
Common uses for bc are:
computation with large integers
computations accurate to many decimal places
conversions of numbers from one base to another base
There is a scaling provision that permits the use of decimal point
notation. Provision is made for input and output in bases other than
decimal. Numbers can be converted from decimal to octal simply by
setting the output base equal to 8.
The actual limit on the number of digits that can be handled depends
on the amount of storage available on the machine, so manipulation
of numbers with many hundreds of digits is possible.
Tasks
This section describes how to perform common bc tasks.
Computing with integers
The simplest kind of statement is an arithmetic expression on a line
by itself. For instance, the expression:
142857 + 285714
when evaluated, responds immediately with the line:
428571
Other operators can also be used. The complete list includes:
+ - * / % ^
They indicate addition, subtraction, multiplication, division,
modulo (remaindering), and exponentiation, respectively. Division of
integers produces an integer result truncated toward zero. Division
by zero produces an error message.
Any term in an expression can be prefixed with a minus sign to
indicate that it is to be negated (this is the ``unary'' minus
sign). For example, the expression:
7 + -3
is interpreted to mean that -3 is to be added to 7.
More complex expressions with several operators and with parentheses
are interpreted just as in FORTRAN, with exponentiation
(^) performed first, then multiplication (*), division (/),
modulo (%), and finally, addition (+), and subtraction (-).
The contents of parentheses are evaluated before expressions outside
the parentheses. All of the above operations are performed from left
to right, except exponentiation, which is performed from right to
left.
Thus the following two expressions:
a^b^c and a^(b^c)
are equivalent, as are the two expressions:
a*b*c and (a*b)*c
bc shares with FORTRAN and C the
convention that a/b*c is equivalent to (a/b)*c.
Internal storage registers to hold numbers have single lowercase
letter names. The value of an expression can be assigned to a
register in the usual way, thus the statement:
x = x + 3
has the effect of increasing by 3 the value of the contents of the
register named x. When, as in this case, the outermost
operator is the assignment operator (=), then the assignment is
performed but the result is not printed. There are 26 available
named storage registers, one for each letter of the alphabet.
There is also a built-in square root function whose result is
truncated to an integer (see also ``Scaling quantities'', below).
For example, the lines:
x = sqrt(191)
x
produce the printed result:
13
Specifying input and output bases
There are special internal quantities in bc, called
ibase (or base) and
obase. base and ibase can be used
interchangeably. ibase is initially set to 10, and
determines the base used for interpreting numbers that are read in
to bc. For example, the lines:
ibase = 8 11
produce the output line:
9
and set up bc to do octal to decimal conversions. Beware
of trying to change the input base back to decimal by entering:
ibase = 10
Because the number 10 is interpreted as octal, this statement has no
effect. For those who deal in hexadecimal notation, the uppercase
characters A-F are permitted in numbers (no matter what base is in
effect) and are interpreted as digits having values 10-15,
respectively. These characters must be uppercase and not
lowercase.
The statement:
ibase = A
changes back to decimal input base no matter what the current input
base is. Negative and large positive input bases are permitted;
however no mechanism has been provided for the input of arbitrary
numbers in bases less than 1 and greater than 16.
obase is used as the base for output numbers. The value of
obase is initially set to a decimal 10.
The lines:
obase = 16 1000
produce the output line:
3E8
This is interpreted as a three-digit hexadecimal number. Very large
output bases are permitted. For example, large numbers can be output
in groups of five digits by setting obase to 100000. Even
strange output bases, such as negative bases, and 1 and 0, are
handled correctly.
Very large numbers are split across lines with seventy characters
per line. A split line that continues on the next line ends with a
backslash (\). Decimal output conversion is fast, but output of
very large numbers (that is, more than 100 digits) with other bases
is rather slow.
The values of ibase and obase do not affect the
course of internal computation or the evaluation of expressions;
they only affect input and output conversion.
Scaling quantities
A special internal quantity called scale is used to
determine the scale of calculated quantities. Numbers can have up to
99 decimal digits after the decimal point. This fractional part is
retained in further computations. We refer to the number of digits
after the decimal point of a number as its scale.
When two scaled numbers are combined by means of one of the
arithmetic operations, the result has a scale determined by the
following rules:
Addition, subtraction
The scale of the result is the larger of the scales of the two
operands. There is never any truncation of the result.
Multiplication
The scale of the result is never less than the maximum of the two
scales of the operands, and never more than the sum of the scales of
the operands, and subject to those two restrictions, the scale of
the result is set equal to the contents of the internal quantity,
scale.
Division
The scale of a quotient is the contents of the internal quantity,
scale.
Modulo
The scale of a remainder is the sum of the scales of the quotient
and the divisor.
Exponentiation
The result of an exponentiation is scaled as if the implied
multiplications were performed. An exponent must be an integer.
Square Root
The scale of a square root is set to the maximum of the scale of the
argument and the contents of scale.
All of the internal operations are actually carried out in terms of
integers, with digits being discarded when necessary. In every case
where digits are discarded truncation is performed without rounding.
The contents of scale must be no greater than 99 and no
less than 0. It is initially set to 0.
The internal quantities scale, ibase, and
base can be used in expressions just like other
variables. The line:
scale = scale + 1
increases the value of scale by 1, and the line:
scale
causes the current value of scale to be printed.
The value of scale retains its meaning as a number of
decimal digits to be retained in internal computation even when
ibase or obase are not equal to 10. The internal
computations (which are still conducted in decimal, regardless of
the bases) are performed to the specified number of decimal digits,
never hexadecimal, octal or any other kind of digits.
Using functions
The name of a function is a single lowercase letter. Function names
are permitted to use the same letters as simple variable
names. Twenty-six different defined functions are permitted in
addition to the twenty-six variable names.
The line:
define a(x){
begins the definition of a function with one argument. This line
must be followed by one or more statements, which make up the body
of the function, ending with a right brace (}). Return
of control from a function occurs when a return statement
is executed or when the end of the function is reached.
The return statement can take either of the two forms:
return
return(x)
In the first case, the returned value of the function is 0; in the
second, it is the value of the expression in parentheses.
Variables used in functions can be declared as automatic by a
statement of the form:
auto x,y,z
There can be only one auto statement in a function and it
must be the first statement in the definition. These automatic
variables are allocated space and initialized to zero on entry to
the function and thrown away on return. The values of any variables
with the same names outside the function are not
disturbed. Functions can be called recursively and the automatic
variables at each call level are protected. The parameters named in
a function definition are treated in the same way as the automatic
variables of that function, with the single exception that they are
given a value on entry to the function.
An example of a function definition follows:
define a(x,y){
auto z
z = x*y
return(z)
}
The value of this function, when called, is the product of its two
arguments.
A function is called by the appearance of its name, followed by a
string of arguments enclosed in parentheses and separated by
commas. The result is unpredictable if the wrong number of arguments
is used.
If the function do_something is defined as shown above,
then the line:
do_something(7,3.14)
prints the result:
21.98
Similarly, the line:
x = do_something(do_something(3,4),5)
causes the value of x to become 60.
Functions without arguments can still perform useful operations or
return useful results. Such functions are defined and called using
parentheses with nothing between them. For example:
b ()
calls the function named b.
Using subscripted variables
A single lowercase letter variable name followed by an expression in
brackets is called a subscripted variable and indicates an array
element. The variable name is the name of the array and the
expression in brackets is called the subscript. Only one-dimensional
arrays are permitted in bc. The names of arrays are
permitted to collide with the names of simple variables and function
names. Any fractional part of a subscript is discarded before
use. Subscripts must be greater than or equal to 0 and less than or
equal to 2047.
Subscripted variables can be freely used in expressions, function
calls and return statements.
An array name can be used as an argument to a function, as in:
f(a[])
Array names can also be declared as automatic in a function
definition with the use of empty brackets:
define f(a[ ])
auto a[ ]
When an array name is so used, the entire contents of the array are
copied for the use of the function, then thrown away on exit from
the function. Array names that refer to whole arrays cannot be used
in any other context.
Using control statements: if, while and for
The if, while, and for statements are
used to alter the flow within programs or to cause iteration. The
range of each of these statements is a following statement or
compound statement consisting of a collection of statements enclosed
in braces. They are written as follows:
if (relation) statement while (relation) statement for (expression1; relation; expression2) statement
A relation in one of the control statements is an expression of the
form:
expression1 rel-op expression2
where the two expressions are related by one of the six relational
operators:
< > <= >= == !=
Note that a double equal sign (==) stands for ``equal to'' and an
exclamation-equal sign (!=) stands for ``not equal to''. The meaning
of the remaining relational operators is their normal arithmetic and
logical meaning.
Beware of using a single equal sign (=) instead of the double equal
sign (==) in a relational. Both of these symbols are legal, so no
diagnostic message is produced. However, the operation will not
perform the intended comparison.
The if statement causes execution of its range if and only
if the relation is true. Then control passes to the next statement
in the sequence.
The while statement causes repeated execution of its range
as long as the relation is true. The relation is tested before each
execution of its range and if the relation is false, control passes
to the next statement beyond the range of the while
statement.
The for statement begins by executing
expression1. Then the relation is tested and, if true, the
statements in the range of the for statement are
executed. Then expression2 is executed. The relation is
tested, and so on. The typical use of the for statement
is for a controlled iteration, as in the statement:
for (i=1; i<=10; i=i+1)
which will print the integers 1 to 10.
The following are some examples of the use of the control
statements:
define f(n){
auto i, x
x=1
for(i=1; i<=n; i=i+1) x=x*i
return(x)
}
The line:
f(a)
prints a factorial if a is a positive integer.
The following is the definition of a function that computes values
of the binomial coefficient (m and n are assumed
to be positive integers):
The following function computes values of the exponential function
by summing the appropriate series without regard to possible
truncation errors:
scale = 20
define e(x){
auto a, b, c, d, n
a = 1
b = 1
c = 1
d = 0
n = 1
while(1==1) {
a = a*x
b = b*n
c = c + a/b
n = n + 1
if(c==d) return(c)
d = c
}
}
Using other language features
Language features which are less frequently used but still essential
to know about are listed below.
Normally, statements are entered one to a line. It is also
permissible to enter several statements on a line if they are
separated by semicolons.
If an assignment statement is placed in parentheses, it then has a
value and can be used anywhere that an expression can. For example,
the line:
(x=y+17)
not only makes the indicated assignment, but also prints the
resulting value. The following is an example of a use of the value
of an assignment statement even when it is not placed in
parentheses:
x = a[i=i+1]
This causes a value to be assigned to x and also
increments i before it is used as a subscript.
The following constructions work in bc in exactly the same
manner as they do in the C language:
Construction
Equivalent
Notes
x=y=z
x =(y=z)
x += y
x = x+y
x -= y
x = x-y
x = y
x = xy
x /= y
x = x/y
x %= y
x = x%y
x ^= y
x = x^y
x =+ y
x = x+y
obsolete
x =- y
x = x-y
obsolete
x = y
x = xy
obsolete
x =/ y
x = x/y
obsolete
x =% y
x = x%y
obsolete
x =^ y
x = x^y
obsolete
x++
(x=x+1)-1
result is value of x before incrementing
x--
(x=x-1)+1
result is value of x before decrementing
++x
x = x+1
result is value of x after incrementing
--x
x = x-1
result is value of x after decrementing
Note that some of the constructions above are marked
obsolete. Although they are still supported, use of the alternative
constructions is recommended.
If one of these constructions is used inadvertently, it is possible
for something legal but unexpected to happen. There is a real
difference between x=-y and x= -y. The first
replaces x by x-y and the second by
-y.
The comment convention is identical to the C comment
convention. Comments begin with / and end with /.
There is a library of math functions that can be obtained by
entering:
bc -l
when bc is invoked. This command loads the library
functions sine, cosine, arctangent, natural logarithm, exponential,
and Bessel functions of integer order. These are named s,
u, a, l, e, and
j(n,x) respectively. This library sets scale to
20 by default.
If bc is loaded with:
bcfile ...
bc will read and execute the named file or files before
accepting commands from the keyboard. In this way, user programs and
function definitions can be loaded.
Some of these constructions are case-sensitive.
Language reference
This section is a comprehensive reference to the bc
language. It contains a more concise description of the features
mentioned in earlier sections.
Tokens
Tokens are keywords, identifiers, constants, operators, and
separators. Token separators can be blanks, tabs or
comments. Newline characters or semicolons separate statements.
Comments are introduced by the characters / and are terminated
by /.
There are three kinds of identifiers: ordinary identifiers, array
identifiers and function identifiers. All three types consist of
single lowercase letters. Array identifiers are followed by square
brackets, enclosing an optional expression describing a
subscript. Arrays are singly dimensioned and can contain up to 2048
elements. Indexing begins at 0 so an array can be indexed from 0 to
2047. Subscripts are truncated to integers. Function identifiers are
followed by parentheses enclosing optional arguments. The three
types of identifiers do not conflict; a program can have a variable
named x, an array named x, and a function named
x, all of which are separate and distinct.
The following are reserved keywords:
base if sqrt auto
obase break length return
scale define while quit
for
Constants are arbitrarily long numbers with an optional decimal
point. The hexadecimal digits A-F are also recognized as digits with
decimal values 10-15, respectively.
Expressions
All expressions can be evaluated to a value. The value of an
expression is always printed unless the main operator is an
assignment. The precedence of expressions (that is, the order in
which they are evaluated) is as follows:
Named expressions are places where values are stored. Simply stated,
named expressions are legal on the left side of an assignment. The
value of a named expression is the value stored in the place named.
identifiers
Simple identifiers are named expressions. They have an initial value
of 0.
array-name[expression]
Array elements are named expressions. They have an initial value
of 0.
scale, ibase and obase
The internal registers scale, ibase, and
obase are all named expressions. scale is the
number of digits after the decimal point to be retained in
arithmetic operations and has an initial value of 0. ibase
and obase are the input and output number radixes
respectively. Both ibase and obase have initial
values of 10.
Constants are primitive expressions that evaluate to themselves.
An expression surrounded by parentheses is a primitive
expression. The parentheses are used to alter normal operator
precedence.
Function calls are expressions that return values. They are
discussed in the next section.
Function calls
A function call consists of a function name followed by parentheses
containing a comma-separated list of expressions, which are the
function arguments. The syntax is as follows:
A whole array passed as an argument is specified by the array name
followed by empty square 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. Three built-in functions are listed below:
sqrt(expr)
The result is the square root of the expression and 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.
length(expr)
The result is the total number of significant decimal digits in the
expression. The scale of the result is 0.
scale(expr)
The result is the scale of the expression. The scale of the result
is 0.
Unary operators
The unary operators bind right to left.
-expr
The result is the negative of the expression.
++named_expr
The named expression is incremented by 1. The result is the value of
the named expression after incrementing.
--named_expr
The named expression is decremented by 1. The result is the value of
the named expression after decrementing.
named_expr++
The named expression is incremented by 1. The result is the value of
the named expression before incrementing.
named_expr--
The named expression is decremented by 1. The result is the value of
the named expression before decrementing.
Multiplicative operators
The multiplicative operators (*, /, and %) bind from left to right.
expr*expr
The result is the product of the two expressions. If a and
b are the scales of the two expressions, then the scale of
the result is:
min(a+b,max(scale,a,b))
expr/expr
The result is the quotient of the two expressions. The scale of the
result is the value of scale.
expr%expr
The modulo operator (%) produces the remainder of the division of
the two expressions. More precisely, a%b is
a-a/b*b. The scale of the
result is the sum of the scale of the divisor and the value of
scale.
expr^expr
The exponentiation operator binds right to left. The result is the
first expression raised to the power of the second expression. The
second expression must be an integer. If a is the scale of
the left expression and b is the value of the right
expression, then the scale of the result is:
for b >= 0:
min(a*b,max(scale,a))
for b < 0:
scale
Additive operators
The additive operators bind left to right.
expr+expr
The result is the sum of the two expressions. The scale of the
result is the maximum of the scales of the expressions.
expr-expr
The result is the difference of the two expressions. The scale of
the result is the maximum of the scales of the expressions.
Assignment operators
The assignment operators listed below assign values to the named
expression on the left side. The operators bind right to left.
named_expr=expr
This expression results in assigning the value of the expression on
the right to the named expression on the left.
named_expr+=expr named_expr=+expr (obsolete)
The result of this expression is equivalent to:
named_expr=named_expr+expr.
named_expr-=expr named_expr=-expr (obsolete)
The result of this expression is equivalent to:
named_expr=named_expr-expr.
named_expr=expr named_expr=expr (obsolete)
The result of this expression is equivalent to:
named_expr=named_exprexpr.
named_expr/\=expr named_expr=/expr (obsolete)
The result of this expression is equivalent to:
named_expr=named_expr/expr.
named_expr%=expr named_expr=%expr (obsolete)
The result of this expression is equivalent to:
named_expr=named_expr%expr.
named_expr^=expr named_expr=^expr (obsolete)
The result of this expression is equivalent to:
named_expr=named_expr^expr.
Relational operators
Unlike other operators, the relational operators are only valid as
the object of an if or while statement, or
inside a for statement.
There are only two storage classes in bc: global and
automatic (local). Only identifiers that are to be local to a
function need to be declared with the auto command. 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. They,
therefore, do not retain values between function calls. Note that
auto arrays are specified by the array namer, followed by
empty square brackets.
Automatic variables in bc do not work the same way as in
C. 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 return is made from the function, reference to these
names is only to the new values.
Statements
Statements must be separated by a semicolon or a newline. Except
where altered by control statements, execution is sequential. There
are four types of statements: expression statements, compound
statements, quoted string statements, and built-in statements. Each
kind of statement is discussed below:
Expression statements
When a statement is an expression, unless the main operator is an
assignment, the value of the expression is printed, followed by a
newline character.
Compound statements
Statements can be grouped together and used when one statement is
expected by surrounding them with curly braces ({ and }).
Quoted string statements
For example ``string'' prints the string inside the
quotation marks.
Built-in statements
Built-in statements include auto, break,
define, for, if, quit,
return, and while.
The syntax for each built-in statement is given below:
auto
The auto statement 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. Syntax of the
auto statement is:
autoidentifier [, identifier]
break
The break statement causes termination of a for
or while statement. Syntax for the break
statement is:
break
define
The define statement defines a function; parameters to the
function can be ordinary identifiers or array names. Array names
must be followed by empty square brackets. The syntax of the
define statement is:
first-expression while (relation) { statement last-expression }
All three expressions must be present. Syntax of the for
statement is:
for (expression; relation; expression) statement
if
The if statement is executed if the relation is true. The
syntax is as follows:
if (relation) statement
quit
The quit statement stops execution of a bc
program and returns control to the operating system when it is first
encountered. Because it is not treated as an executable statement,
it cannot be used in a function definition or in an if,
for, or while statement. Note that entering a
<Ctrl>d at the keyboard is the same as entering
``quit''. The syntax of the quit statement is as follows:
quit
return
The return statement terminates a function, pops its auto
variables off the stack, and specifies the result of the
function. The result of the function is the result of the expression
in parentheses. The first form is equivalent to ``return(0)''. The
syntax of the return statement is as follows:
return(expr)
while
The while statement is executed while the relation is
true. The test occurs before each execution of the statement. The
syntax of the while statement is as follows: