Format
bc [–i]
[–l] [file]
Description
bc is
a programming language that can perform arithmetic calculations to
arbitrary precision. You can use it interactively, by entering instructions
from the terminal. It can also run programs taken from files.
The file arguments
you specify on the command line should be text files containing bc instructions. bc runs
the instructions from those files, in the order that they appear on
the command line, and then runs instructions from the standard input
(stdin). bc ends when it runs a quit instruction
or reaches the end of the file on stdin.
bc is
a simple but complete programming language with a syntax reminiscent
of the C programming language. This version of bc is
a superset of the standard language available on most systems. It
has a number of additional features intended to make the language
more flexible and useful. Features unique to this implementation are
noted.
Input consists of a series of instructions that assign
values to variables or make calculations. It is also possible to define
subprograms called functions, which perform a sequence of instructions
to calculate a single value.
bc displays
the result of any line that calculates a value, but does not assign
it to a variable. For example, the instruction:
2+2
By default, bc displays
the result of any evaluated instruction followed by a newline. bc also
saves the last value displayed in a special variable . (dot),
so that you can use it in subsequent calculations.
For a summary
of the UNIX03 changes to this command, see Shell commands changed for UNIX03.
Options
bc supports
the following options.
- –i
- Puts bc into interactive mode with a
displayed prompt. In this mode, bc displays
a prompt, which is : (waiting for input). In addition, it handles
errors differently. Typically, when bc encounters
an error while processing a file, the interpreter displays the error
message and exits. In interactive mode, the interpreter displays the
message and returns to the prompt mode to allow debugging.
- –l
- Loads a library of standard mathematical functions before processing
any other input. This library also sets the scale to
20. For a description of the functions in the –l library,
see Built-in functions.
Numbers
Numbers consist of an optional
minus (-) sign or an optional plus (+)
sign followed by a sequence of zero or more digits, followed by an
optional decimal point (.), followed by a sequence
of zero or more digits. Valid digits are 0 through 9,
and the hexadecimal digits A through F.
The uppercase letters represent the values from 10 through 15.
There must be at least one digit, either before or after the decimal
point. If not, bc interprets the decimal
point as the special variable ..
A number
can be arbitrarily long and can contain spaces. Here are some valid
numbers with an input base of 10:
0 0. .0 -3.14159 +09. -12 1 000 000
Here
are some valid numbers with an input base of 16 (
ibase=16):
0 FF FF.3 -10.444 A1
See Bases for more information.
Restriction: You
cannot break up numbers with commas; you can write 1000000 or 1
000 000, but 1,000,000 results in an error
message.
Identifiers
Identifiers can include
sequences containing any number of letters, digits, or the underscore
(_) character but must start with a lowercase letter.
Spaces are not allowed in identifiers.
In the POSIX locale,
valid identifiers can include sequences containing any number of letters,
digits, or the underscore (_) character but must start with a lowercase
letter, as defined by the current locale.
For other locales,
the character map for that locale determines which characters are
valid in an identifier. If you want identifiers to be portable between
locales, use characters from the POSIX character set. The use of identifiers
longer than one character is an extension of this implementation.
Identifiers are used as names for variables, functions, or arrays:
- A variable holds a single numeric value. You can declare
variables that are local to a function using the auto statement.
(See Functions.) All other variables
are global and you can use them inside any function or outside all
functions. You do not need to declare global variables. bc creates
variables as it requires them, with an initial value of zero. (Remember
that there is also the special variable . [dot],
which contains the result of the last calculation.)
- A function is a sequence of instructions that calculates
a single value. A list of zero or more values enclosed in parentheses
always follow a function name, as in my_func(3.14159). (See Functions.)
- An array is a list of values. Values in the list are called elements of
the array. These elements are numbered, beginning at zero. We call
such a number a subscript, or index, of the array. Subscripts
always appear in square brackets after the array. For example, a[0] refers
to element zero in the array a. The first
element of the array always has the subscript 0.
If a subscript value is a floating-point number, the fractional part
is discarded to make the subscript into an integer. For example, the
following expressions all refer to the same element:
a[3] a[3.2] a[3.999]
The
maximum number of elements in a bc array
is in the range from 0 to {BC_DIM_MAX}-1
inclusive. Unlike with many languages, you do not need to declare
the size of an array. Elements are created dynamically as required,
with an initial value of zero.
Since parentheses always follow function names and square
brackets always follow array names, bc can
distinguish between all three types of names—variable names,
function names, and array names. Therefore, you can have variables,
functions, and arrays with the same name. For example, foo may
be a variable whereas foo() is a function
and foo[ ] is an array.
Built-in variables
bc has
a number of built-in variables that are used to control various aspects
of the interpreter. These are described in the following topics.
Scale
The
scale value is the number
of digits to be retained after the decimal point
in arithmetic operations. For example, if the scale is 3, each calculation
retains at least three digits after the decimal point. This means
that:
5 / 3
has the value:
1.666
If –l is
specified, the scale is set to 20; otherwise, the default scale is
zero.
The variable
scale holds the
current scale value. To change scales, assign a new value to
scale,
as in:
scale = 5
Since scale is
just a regular bc variable, it can be used
in the full range of bc expressions.
The
number of decimal places in the result of a calculation is affected
not only by the scale, but also by the number of decimal places in
the operands of the calculation. Arithmetic
operations discusses this.
There is also a function scale,
which can determine the scale of any expression. For example, scale(1.1234) returns
the result 4, which is the scale of the number 1.1234. The result
of the scale function is always an integer
(that is, it has the scale of 0).
The maximum
value for scale is given by the configuration
variable {BC_SCALE_MAX} and the minimum value is 0.
Bases
bc lets
you specify numbers in different bases—for
example, octal (base 8) or hexadecimal (base 16). You can input numbers
in one base and output them in a different base, simplifying the job
of converting from one base to another. bc does
this using the built-in variables ibase and obase.
ibase is
the base for input numbers. It has an initial value of 10 (normal
decimal numbers). To use a different base for inputting numbers, assign
an integer to
ibase, as in:
ibase = 8
This
means that all future input numbers are to be in base 8 (octal). The
largest valid input base is 16, and the smallest valid input base
is 2. There is no mechanism provided to represent digits larger than
15, so bases larger than 16 are essentially useless. When the base
is greater than 10, use the uppercase letters as digits. For example,
base 16 uses the digits
0 through
9,
and
A through
F. The digits are
allowed in any number, regardless of the setting of
ibase but
are largely meaningless if the base is smaller than the digit. The
one case where this is useful is in resetting the input base to 10.
The constant
A always has the value 10 no matter
what
ibase is set to, so to reset the input
base to 10, type:
ibase = A
obase is
the base in which numbers are output. It has an initial value of 10
(normal decimal numbers). To change output bases, assign an appropriate
integer to obase.
If the output base
is 16 or less,
bc displays numbers with
normal digits and hexadecimal digits (if needed). The output base
can also be greater than 16, in which case each
digit is printed
as a decimal value and digits are separated by a single space. For
example, if
obase is 1000, the decimal number
123 456 789 is printed as:
123 456 789
Here,
the digits are decimal values from 0 through 999.
As a result, all output values are broken up into one or more chunks with
three digits per chunk. Using output bases that are large powers of
10, you can arrange your output in columns; for example, many users
find that 100 000 makes a good output base, because numbers are
grouped into chunks of five digits each.
Long
numbers are output with a maximum of 70 characters per line. If a
number is longer than this, bc puts a backslash
(\) at the end of the line indicating that the number
is continued on the next line. The backslash (\)
and newline characters are counted as part of the
70 character length.
Internal calculations are performed in
decimal, regardless of the input and output bases. Therefore the number
of places after the decimal point are dictated by the scale when numbers
are expressed in decimal form.
The maximum value for obase is
given by the configuration variable {BC_BASE_MAX}.
Arithmetic operations
bc provides
a large number of arithmetic operations. Following standard arithmetic
conventions, some operations are calculated before others. For example,
multiplications take place before additions unless you use parentheses
to group operations. Operations that take place first are said to
have a higher precedence than operations that take place later.
Operations
also have an
associativity. The associativity dictates the
order of evaluation when you have a sequence of operations with equal
precedence. Some operations are evaluated left to right, whereas others
are evaluated right to left. The following list shows the operators
of
bc from highest precedence to lowest.
- bc operator
- Associativity
- ( )
- Left to right
- Unary ++ --
- Not applicable
- Unary - !
- Not applicable
- ^
- Right to left
- * / %
- Left to right
- + -
- Left to right
- = ^= *= /= %= +=
- Right to left
- == <= >= != < >
- None
- &&
- Left to right
- ||
- Left to right
bc’s order
of precedence is not the same as C’s. In C, the assignment operators
have the lowest precedence.
The following list describes what
each operation does. In the descriptions,
A and
B can
be numbers, variables, array elements, or other expressions.
V must
be either a variable or an array element.
- (A)
- Indicates that this expression—A—should
be evaluated before any other operations are performed on it.
- -A
- Is the negation of the expression.
- !A
- Is the logical complement of the expression. If A evaluates
to zero, !A evaluates to 1. If A is
not zero, !A evaluates to zero. This operator is
unique to this version of bc.
- ++V
- Adds 1 to the value of V. The
result of the expression is the new value of V.
- - -V
- Subtracts 1 from the value of V.
The result of the expression is the new value of V.
- V++
- Adds 1 to the value of V, but
the result of the expression is the old value of V.
- V- -
- Subtracts 1 from the value of V,
but the result of the expression is the old value of V.
- A ^ B
- Calculates A to the power B. B must
be an integer. The scale of the result of A^B is:
min(scale(A) * abs(B), max(scale, scale(A)))
where min calculates
the minimum of a set of numbers and max calculates
the maximum.
- A * B
- Calculates A multiplied by B.
The scale of the result is:
min(scale(A) + scale(B), max(scale, scale(A), scale(B)))
- A / B
- Calculates A divided by B. The
scale of the result is the value of scale.
- A % B
- Calculates the remainder from the division of A by B.
This is calculated in two steps. First, bc calculates A/B to
the current scale. It then obtains the remainder through the formula:
A - (A / B) * B
calculated to the scale:
max(scale + scale(B), scale(A))
- A + B
- Adds A plus B. The scale of
the result is the maximum of the two scales of the operands.
- A-B
- Calculates A minus B. The scale
of the result is the maximum of the two scales of the operands.
Therefore, you can write such operations as
a=1+(b=2).
In this operation, the value of the assignment in parentheses is
2 because
that is the value assigned to
b. Therefore, the value
3 is
assigned to
a. The possible assignment operators
are:
- V = B
- Assigns the value of B to V.
- V ^= B
- Is equivalent to V=V^B.
- V *= B
- Is equivalent to V=V*B.
- V /= B
- Is equivalent to V=V/B.
- V %= B
- Is equivalent to V=V%B.
- V += B
- Is equivalent to V=V+B.
- V -= B
- Is equivalent to V=V-B.
The next group of operators are all assignment operators.
They assign values to objects. An assignment operation has a value,
which is the value that is being assigned.
The
following expressions are called
relations,
and their values can be either true (
1) or false
(
0). This version of
bc lets
you use the relational operators in any expression, not just in the
conditional parts of
if,
while,
or
for statements. These operators work
exactly like their equivalents in the C language. The result of a
relation is
0 if the relation is false and
1 if
the relation is true.
- A == B
- Is true if and only if A equals B.
- A <= B
- Is true if and only if A is less than or equal
to B.
- A >= B
- Is true if and only if A is greater than or equal
to B.
- A != B
- Is true if and only if A is not equal to B.
- A < B
- Is true if and only if A is less than B.
- A > B
- Is true if and only if A is greater than B.
- A && B
- Is true if and only if A is true (nonzero) and B is
true. If A is not true, the expression B is
never evaluated.
- A || B
- Is true if A is true or B is
true. If A is true, the expression B is
never evaluated.
Comments and white space
A
comment has
the form:
/* Any string */
Comments
can extend over more than one line of text. When
bc sees
/* at
the start of a comment, it discards everything up to the next */.
The only effect a comment has is to indicate the end of a token. As
an extension, this version of
bc also provides
an additional comment convention using the
# character.
All text from the
# to the end of the line is treated
as a single blank, as in:
2+2 # this is a comment
bc is
free format. You can freely insert blanks or horizontal tab characters
to improve the readability of the code. Instructions are assumed to
end at the end of the line. If you have an instruction that is so
long you need to continue it on a new line, put a backslash (
\)
as the very last character of the first line and continue on the second,
as in:
a = 2\
+ 3
The
\ indicates that the
instruction continues on the next line, so this is equivalent to:
a = 2 + 3
Instructions
A
bc instruction
can be an expression that performs a calculation, an assignment, a
function definition, or a statement. If an instruction is not an assignment,
bc displays
the result of the instruction when it has completed the calculation.
For example, if you enter:
3.14 * 23
bc displays
the result of the calculation. However, with:
a = 3.14 * 23
bc does
not display anything, because the expression is an assignment. If
you do want to display the value of an assignment expression, simply
place the expression in parentheses.
The following list shows
the instruction forms recognized by
bc:
- expression
- Calculates the value of the expression.
- “string”
- Is a string constant. When bc sees a
statement of this form, it displays the contents of the string. For
example:
"Hello world!"
tells
bc to
display
Hello world! A newline character is
not output
after the string. This makes it possible to do things like:
foo = 15
"The value of foo is "; foo
With these instructions,
bc displays
The value of foo is 15
- statement ; statement …
- Is a sequence of statements on the same line. In bc,
a semicolon (;) and a newline are equivalent. They
both indicate the end of a statement. bc runs
these statements in order from left to right.
- {statement}
- Is a brace-bracketed statement. Brace brackets are used to group
sequences of statements together, as in:
{
statement
statement
…
}
Brace brackets can group a series of statements that
are split over several lines. Braces are typically used with control
statements like if and while.
- break
- Can be used only inside a while or for loop. break ends
the loop.
- for (initexp ; relation ; endexp) statement
- Is equivalent to:
initexp
while (relation) {
statement
endexp
}
where
initexp and
endexp are
expressions and
relation is a relation.
For example:
a = 0
for (i = 1; i <= 10; ++i) a += i
is equivalent
to the while example given earlier. Rule: All
three items inside the parentheses must be specified. Unlike C, bc does
not let you omit any of these expressions.
- if (relation)statement
- Tests whether the given relation is
true. If so, bc runs the statement;
otherwise, bc skips over the statement and
goes to the next instruction. For example:
if ((a%2) == 0) "a is even"
displays a
is even if a has an even value.
- if (relation) statement1 elsestatement2
- Is similar to the simple if statement.
It runs statement1 if relation is
true and otherwise runs statement2. It may
be used as follows:
if ((a%2) == 0) "a is even" else "a is odd"
There
is no statement separator between “a is even” and the else keyword.
This differs from the C language
Here is another example:
if (a<10) {
"a "
"is "; "less than 10 "
a
} else {
"a is"
" greater than 10 "
a
}
Rule: The braces must be on the same line
as the if and the else keywords.
This is because a new line or a semicolon right after (relation)
indicates that the body of the statement is null. One common source
of errors in bc programs is typing the statement
body portion of an if statement on a separate
line. If –i is used, the interpreter
displays a warning when if statements with
null bodies are encountered.
- while (relation)statement
- Repeatedly runs the given statement while relation is
true. For example:
i = 1
a = 0
while (i <= 10) { a += i
++i
}
adds the integers from 1 through 10 and stores the
result in a.
If relation is
not true when bc encounters the while loop, bc does
not run statement at all.
- print expression , expression
…
- Displays the results of the argument expressions. Normally, bc displays
the value of each expression or string it encounters. This makes it
difficult to format your output in programs. For this reason, the z/OS shell version
of bc has a print statement
to give you more control over how things are displayed. print lets
you display several numbers on the same line with strings. This statement
displays all its arguments on a single line. A single space is displayed
between adjacent numbers (but not between numbers and strings). A print statement
with no arguments displays a newline. If the last argument is null,
subsequent output continues on the same line. Here are some examples
of how to use print:
/* basic print statement */
print "The square of ", 2, "is ", 2*2
The square of 2 is 4
/* inserts a space between adjacent numbers */
print 1,2,3
1 2 3
/* note - no spaces */
print 1,"",2,"",3
123
/* just print a blank line */
print
/* two statements with output on same line */
print 1,2,3, ; print 4, 5, 6
1 2 3 4 5 6
- quit
- Ends bc. In other implementations of bc,
the interpreter exits as soon as it reads this token. This version
of bc treats quit as
a real statement, so you can use it in loops, functions, and so on.
- sh …
- Lets you send a line to the system command interpreter for execution,
as in:
sh more <foo
This command passes
everything from the first nonblank character until the end of the
line to the command interpreter for execution.
- void expression
- Throws away, or “voids,” the result of the evaluation
of expression instead of displaying it.
This instruction is useful when using ++ and -- operators,
or when you want to use a function but don't want to use the return
value for anything. For example:
void foo++
increments foo but
does not display the result. The void statement
is unique to this version of bc.
Several other types of statements are relevant
only in function definitions. These are described in the next topic.
Functions
A function is a
subprogram to
calculate a result based on
argument values.
For example, the following function converts a temperature given in
Fahrenheit into the equivalent temperature in Celsius:
define f_to_c(f) {
return ((f-32) * 5 / 9)
}
This defines a function named
f_to_c() that
takes a single argument called
f. The
body of
the function is enclosed in brace brackets. The opening brace must
be on the same line as the
define keyword.
The function body consists of a sequence of statements to calculate
the
result of the function. An expression of the form:
return (expression)
returns
the value of expression as the result of
the function. The parentheses around the expression are optional.
To
activate the subprogram you use a
function call. This has the
form:
name(expression,expression,…)
where name is
the name of the function, and the expressions
are argument values for the function. You can use function call anywhere
you might use any other expression. The value of the function call
is the value that the function returns. For example, with the function f_to_c(),
described earlier, f_to_c(41) has the value 5 (since
41 Fahrenheit is equivalent to 5 Celsius).
The general form
of a function definition is:
define name(parameter,parameter,…) {
auto local, local, …
statement
statement
…
}
Each
parameter on the
first line can be a variable name or an array name. Array names are
indicated by putting square brackets after them. For example, if
cmpvec is
a function that compares two vectors, the function definition might
start with:
define cmpvec(a[],b[]) {
Parameters
do not conflict with arrays or variables of the same name. For example,
you can have a parameter named a inside a function,
and a variable named a outside, and the two are considered
entirely separate entities. Assigning a value to the variable does
not change the parameter and vice versa. All parameters are passed
by value. This means that a copy is made of the argument value
and is assigned to the formal parameter. This also applies to arrays.
If you pass an array to a function, a copy is made of the whole array,
so any changes made to the array parameter do not affect the original
array.
A function may not need any arguments. In this case,
the
define line does not have any parameters
inside the parentheses, as in:
define f() {
The auto statement
declares a sequence of local variables. When a variable or array name
appears in an auto statement, the current
values of those items are saved and the items are initialized to zero.
For the duration of the function, the items have their new values.
When the function ends, the old values of the items are restored.
However, bc uses
dynamic scoping rules, unlike C which
uses lexical scoping rules. Usage notes for more information.
For
example:
define addarr(a[],l) {
auto i, s
for (i=0; i < l; ++i) s += a[i]
return (s)
}
is a function that adds the elements in an array.
The argument
l stands for the number of elements
in the array. The function uses two local names: a variable named
i and
a variable named
s. These variables are
“local” to the function
addarr and are unrelated
to objects of the same name outside the function (or in other functions).
Objects that are named in an
auto statement
are called
autos. Autos are initialized to
0 each
time the function is called. Thus, the sum
s is
set to zero each time this function is called. You can also have local
arrays, which are specified by placing square brackets after the array
name in the
auto statement.
define func_with_local_array() {
auto local_array[];
for(i=0; i<100; i++) local_array[i] = i*2
}
This example defines a local array called local_array.
Local arrays start out with no elements in them.
If a function
refers to an object that is not a parameter and not declared
auto,
the object is assumed to be
external. External objects may
be referred to by other functions or by statements that are outside
of functions. For example:
define sum_c(a[ ],b[ ],l) {
auto i
for (i=0; i < l; ++i) c[i] = a[i] + b[i]
}
refers to an external array named c,
which is the element-by-element sum of two other arrays. If c did
not exist prior to calling sum_c, it is created dynamically.
After the program has called sum_c, statements in the program
or in functions can refer to array c.
Functions
typically require a
return statement. This has the
form:
return (expression)
The argument expression is
evaluated and used as the result of the function. The expression must
have a single numeric value; it cannot be an array.
A
return statement
ends a function, even if there are more statements left in the function.
For example:
define abs(i) {
if (i < 0) return (-i)
return (i)
}
is a function that returns the absolute value
of its argument. If i is less than zero,
the function takes the first return; otherwise,
it takes the second.
A function can also end by running the
last statement in the function. If so, the result of the function
is zero. The function sum_c is an example of a function that
does not have a return statement. The function
does not need a return statement, because
its work is to calculate the external array c,
not to calculate a single value. Finally, if you want to return from
a function, but not return a value you can use return() or
simply return. If there are no parameters
to the return statement, a default value
of zero is returned.
Built-in functions
bc has
a number of built-in functions that perform various operations.
These functions are similar to user-defined functions. You do not
have to define them yourself, however; they are already set up for
you. These functions are:
- length(expression)
- Calculates the total number of decimal digits in expression.
This includes digits both before and after the decimal point. The
result of length() is an integer. For example, length(123.456) returns 6.
- scale(expression)
- Returns the scale of expression. For
example, scale(123.456) returns 3.
The result of scale() is always an integer.
Subtracting the scale of a number from the length of a number lets
you determine the number of digits before the decimal point.
- sqrt(expression)
- Calculates the square root of the value of expression.
The result is truncated in the least significant decimal place (not
rounded). The scale of the result is the scale of expression,
or the value of scale(), whichever is larger.
You can use the following functions if
–l is
specified on the command line. If it is not, the function names are
not recognized. There are two names for each function: a full name,
and a single character name for compatibility with
POSIX.2POSIX.2. The
full names are the same as the equivalent functions in the standard
C math library.
- arctan(expression)
or a(expression)
- Calculates the arctangent of expression,
returning an angle in radians. This function can also be called as atan(expression).
- bessel(integer,expression)
or j(integer,expression)
- Calculates the Bessel function of expression,
with order integer. This function can also
be called as jn(integer,expression).
- cos(expression)
or c(expression)
- Calculates the cosine of expression,
where expression is an angle in radians.
- exp(expression)
or e(expression)
- Calculates the exponential of expression (that
is, the value e to the power of expression).
- ln(expression)
or l(expression)
- Calculates the natural logarithm of expression.
This function can also be called as log(expression).
- sin(expression)
or s(expression)
- Calculates the sine of expression, where expression is
an angle in radians.
The scale value
of the result returned by these functions is the value of the scale variable
at the time the function is invoked. The value of the scale variable
after these functions have completed their execution will be the same
value it had upon invocation.
Examples
- Here is a simple function to calculate the sales tax on a purchase.
The amount of the purchase is given by purchase,
and the amount of the sales tax (in per cent) is given by tax.
define sales_tax(purchase,tax) {
auto old_scale
scale = 2
tax = purchase*(tax/100)
scale = old_scale
return (tax)
}
For example:
sales_tax(23.99,6)
calculates
6% tax on a purchase of $23.99. The function temporarily sets the
scale value to 2 so that the monetary figures have two figures after
the decimal point. Remember that bc truncates
calculations instead of rounding, so some accuracy may be lost. It
is better to use one more digit than needed and perform the rounding
at the end. The round2 function, shown later
in this topic, rounds a number to two decimal places.
- Division resets the scale of a number to the value of scale.
You can use this to extract the integer portion of a number, as follows:
define integer_part(x) {
# a local to save the value of scale
auto old_scale
# save the old scale, and set scale to 0
old_scale = scale; scale=0
# divide by 1 to truncate the number
x /= 1
# restore the old scale
scale=old_scale
return (x)
}
- Here is a function you can define to return the fractional part
of a number:
define fractional_part(x) {return (x - integer_part(x))}
- The following function lets you set the scale of number to a given
number of decimal places:
define set_scale(x, s)
{ auto os
os = scale
scale = s
x /= 1
scale = os
return (x) }
You can now use
set_scale() in
a function that rounds a number to two decimal places:
define round2(num) {
auto temp;
if(scale(num) < 2) return (set_scale(num, 2))
temp = (num - set_scale(num, 2)) * 1000
if(temp > 5) num += 0.01
return (set_scale(num,2))
}
This is a very useful function if you want to
work with monetary values. For example, you can now rewrite
sales_tax() to
use
round2():
define sales_tax(purchase,tax) {
auto old_scale
scale = 2
tax = round2(purchase*(tax/100))
scale = old_scale
return (tax)
}
- Here is a function that recursively calculates the factorial of
its argument:
define fact (x) {
if(x < 1) return 1
return (x*fact(x-1))
}
You can also write the factorial function iteratively:
define fact (x) {
auto result
result = 1
while(x>1) result *= x--
return (result)
}
With either version, fact(6) returns 720.
- Here is another recursive function, that calculates the nth
element of the Fibonacci sequence:
define fib(n) { if(n < 3) { return (1)
} else {
return (fib(n-1)+fib(n-2))
}
}
Usage notes
- Unlike the C language, which uses lexical scoping rules, bc uses
dynamic scoping, which is most easily explained with an example:
a=10
define f1() {
auto a;
a = 13;
return (f2())
}
define f2() {
return (a)
}
f1()
13
f2()
10
If f1() is called, bc prints
the number 13, instead of the number 10. This is because f1() hides
away the old (global) value of a and then sets it
to 13. When f2() refers to a,
it sees the variable dynamically created by f1() and
so prints 13. When f1() returns, it restores
the old value of a. When f2() is
called directly, instead of through f1(),
it sees the global value for a and prints 10. The
corresponding C code prints 10 in both cases.
- Numbers are stored as strings in the program and converted into
numbers each time they are used. This is important because the value
of a “constant” number may change depending on the setting
of the ibase variable. For example, suppose
that the following instructions are given to bc:
define ten() {
return (10)
}
ten()
10
ibase=16
ten()
16
In this example, when the base is set to 10, ten() returns
the decimal value 10. However, when the input base is changed to 16,
the function returns the decimal value 16. This can be a source of
confusing errors in bc programs.
- The library of functions loaded using the –l option
is stored in the file /usr/lib/lib.b under your root directory.
This is a simple text file that you can examine and change to add
new functions as desired.
- In a noninteractive invocation, bc exits
on any invalid input and the rest of the input are skipped.
Files
bc uses
the following file:
- /usr/lib/lib.b
- File containing the library
of functions loaded with –l
Localization
bc uses
the following localization environment variables:
- LANG
- LC_ALL
- LC_CTYPE
- LC_MESSAGES
- LC_SYNTAX
- NLSPATH
See Localization for more
information.
Exit values
- 0
- Successful completion
- 1
- Failure due to any of the following errors:
- Break statement found outside loop
- Parser stack overflow
- Syntax error
- End of file in comment
- End of file in string
- Numerical constant is too long
- String is too long
- Empty evaluation stack
- Cannot pass scalar to array
- Cannot pass array to scalar
- Incorrect array index
- Built-in variable cannot be used as a parameter or auto variable
- name is not a function
- Incorrect value for built-in variable
- Shell command failed to run
- Division by 0
- Incorrect value for exponentiation operator
- Attempt to take square root of negative number
- Out of memory
- 2
- Unknown command-line option
Limits
The parser stack depth is limited
to 150 levels. Attempting to process extremely complicated programs
may result in an overflow of this stack, causing an error.
Portability
POSIX.2, X/Open Portability Guide, UNIX
systems.
The
following are extensions to the POSIX standard:
- The –i option
- The &&and || operators
- The if … else … statement
- Identifiers of more than one character or containing characters
outside the POSIX character set
- The print statement
- The sh statement
- The optional parentheses in the return statement
In a double-byte environment, remember that only numbers
and operators from the POSIX character set can be used. Identifiers
can use characters from the current locale; if you want scripts to
be portable, use only characters from the POSIX character set.