Using bc, Part 1
An introduction to the programmable calculator utility
Summary
This month, Mo details how to use the bc utility, a programmable calculator that has a few advantages over the expr expression evaluator. The utility allows several types of
calculations and provides simple looping logic. (2,000 words)
In a four-part series that concluded last month, I created a series of shell
scripts that could be used to add or subtract days to a date and to calculate
the day difference between two dates. One reader wrote in and said (and I
paraphrase) "I can do all that in 60 lines of code, so why would you bother to reinvent the wheel?" Following that logic, why do hundreds of thousands of frogs fall prey every year to inquisitive, horrified, or bored biology students? Everyone knows what the students will find inside those slimy bodies, so why bother?
Because this is an introductory Unix column, it is very likely that more than one person will have found a solution to the problems that I'm addressing here. The fact remains that reinventing the wheel can be one of the best ways to learn the details of a process that are often obscured by years of smoothing and refining.
In that spirit, I am going to reinvent the wheel yet again, in order to
illustrate the use of the bc utility, and some shell programming techniques.
The bc utility is a programmable calculator. It allows several types of
calculations and provides simple looping logic. It is also much easier
to read than the expr expression evaluator.
To start bc, type bc at the command line. Once bc begins, you are using
calculator until you type quit. Here is a simple example of using bc. In
the listing, the 4+2 is typed by the user, and bc outputs 6. Finally the user
types quit and presses RETURN to exit bc.
$ bc
4+2
6
quit
$
Using variables
Variables in bc can be used to hold values. Some versions of bc allow only
single character variables, though later versions allow multicharacter
variable names. In all these examples, I will use single character variables in
keeping with the lowest common denominator of bc. In the following listing, the user
assigns a=4, b=5 and c= b-a. Notice that the assignments do not result in any
output from bc. Finally the user types c on a line by itself and bc outputs 1,
the result stored in c after the assignment c=b-a. bc displays the result of
any calculation that is not assigned to a variable. Typing an expression or
variable without an assignment causes the result to be output to the screen.
$ bc
a=4
b=5
c=b-a
c
1
quit
$
A special temporary variable in bc holds the last output. This variable
is a dot. In the following example the user enters 4+2 and bc outputs
6. Then the user enters . (dot) and bc outputs 6, the value held in the
temporary variable, again. The variable can itself be used in an
expression as in .+1, and bc outputs 7. Finally typing . (dot) will
again output 7 because the last output value, 7, has been assigned to .
(dot).
$ bc
4+2
6
.
.+1
7
.
7
quit
$
The number of decimals to be printed by bc is controlled by the scale
variable. The default scale is 0. In the example below, the result of 7/16 is
displayed in different scales, starting with scale=5 and ending with scale=0.
The bc calculator truncates values rather than rounding them.
$ bc
scale=5
7/16
0.43750
scale=3
7/16
0.437
scale=2
7/16
0.43
scale=0
7/16
0
quit
$
Standard operators
Some of the standard bc operators are shown below. Addition (+), subtraction
(-), multiplication (*), and division (/) are fairly standard. Further down
the list you will see remainder division (%) and to the power of (^). In
remainder division the result of the calculation is the remainder of the
division rather than the quotient as in 5%2=1, 15%13=2, 6%3=0, 27%5=2. The
power of operator raises the left hand value to the power of the right hand
value as in 3^2=9, 2^3=8.
$ bc
scale = 0
a=3
b=7
b+a
10
b-a
4
b*a
21
b/a
2
scale=3
b/a
2.333
scale = 0
b%a
1
b^a
343
quit
$
The bc assignment operators assign a value to an operator. They are similar to
the compound assignment operators in C. The first two are simple assignment
(=). The plus equal operator(+=) adds the value in the left hand side of the
assignment to the value on the right hand side of the assignment and stores
the value in the variable on the left hand side of the assignment. The
remaining compound assignment operators (-=, *=, /=, ^=, %=) behave in
analogous ways. When reading the listing below remember that the effect of the
compound operator on a is to alter the value stored in a. Each expression does
not start with a=7, but with the value for a of the last assignment.
$ bc
a = 7
b = 3
a+=2
a
9
a -= 4
a
5
a *= 2
a
10
a /= b
a
3
a ^= 3
a
27
a %= 5
a
2
quit
$
The bc increment and decrement operators are also similar to C, but they have
an extra side effect in bc. Normally an increment or decrement operator adds
or subtracts 1 from a variable as in x++, or --y. Using an increment or
decrement operator causes the variable to be echoed to the screen. In the case of pre-
increment or pre-decrement (++x and --x), the variable is changed and then
echoed to the screen. In the case of post-increment and post-decrement operators
(x++ and x--), the variable is echoed to the screen and then changed.
$ bc
x=1
x++
1
x
2
++x
3
x
3
x--
3
x
2
--x
1
x
1
quit
$
The output to the screen can be suppressed by using the void keyword. This is
useful when you want to use an increment or decrement operator, but don't want
to display the results. In the following example, void prevents the result of
x++ and ++x from being displayed.
$ bc
x=1
void x++
x
2
void ++x
x
3
quit
$
Comparison operators are used in if tests and are the usual is equal (== ), is
less than (<), is greater than (>), is greater than or equal (>=), is less
than or equal (<=) and is not equal (!=). Comparisons can be combined using
and (&&) and or (||).
Control loops
There are two types of control loops in bc. A for loop takes the form:
for(initialization; test ; end expression) statements
In the example below, x=0 sets x to an initial value of zero. The x<10 test
controls how long the for loop will execute, and the ++x indicates what to do
at the end of each loop. Everything within the curly braces is executed. In
this case, the value of x is displayed on the screen resulting is a display of
0 through 9. Note that a statement can be ended with a semicolon (;) or a new
line. This example uses a semicolon.
$ bc
for(x=0;x<10;++x){
x;
}
0
1
2
3
4
5
6
7
8
9
quit
$
A while loop can be used to control a loop as well. This loop produces the
same result as the preceding for loop.
$ bc
x=0
while(x<10{
x;
void ++x;
}
0
1
2
3
4
5
6
7
8
9
quit
$
Just a quick warning to experienced C programmers. The curly braces
surrounding the body of a for or while loop (and the body of if statements
and function definitions which I will cover in a moment) must open on the
same line as the for, while, if or function definition.
Text can be output to the screen by surrounding it with quotes as in the
following example. When you are using bc interactively at a terminal this is
not much use, but it will become useful in writing bc programs. Text is not
followed by a new line, making it possible to display information, as shown in
the following listing.
$ bc
x = 7
"The value of x is "; x;
The value of x is 7
quit
$
I have discussed functions in shell scripts in earlier articles, and functions
in bc are very similar. A function is a series of statements that can be
passed a value and in bc are expected to return a value. In the following
listing a function named s() is created that is passed a value, and will
return the square of the value. When this function is typed in, bc does
nothing with it. So far these commands have only defined the function, but
haven't done anything with it yet. If your version of bc supports identifiers
longer than 1 character, it would be better to name this function square().
$ bc
define s(x){
return(x * x);
}
The next step would be to call the function by requesting the square of 3;
bc responds by printing 9 on the screen. A further request for the square of 8
returns 64.
$ bc
define s(x){
return(x * x);
}
s(3)
9
s(8)
64
Once you type quit and exit from bc, the square function is lost.
Now you have all the pieces that you need to create a bc program. We will
start the first program in next month's article, which will conclude this
series on bc.
Contact
us for a free consultation. |