Arithmetic
The shell itself does contain some rudimentary facilities to do
arithmetic, which we shall discuss later. However, it is not itself
designed for doing such calculations, unlike most high-level
languages. It is recognised, however, that non-trivial arithmetic
will be required by some shell programmers. The solution adopted is
to introduce a utility known as bc ('basic
calculator'), which is a sophisticated calculator. Use of this
utility deserves a chapter in its own right, and we shall merely
touch on the possibilities that bc offers. The
characteristics of bc include
- arbitrary precision arithmetic,
- a complete programming language including for and
while loops and variables, and
- ability to perform arithmetic in bases other than 10.
We omit here the complex structures in bc and
concentrate on using bc to perform simple calculations
in decimal.
By default, bc takes input from standard input;
commands are one per line or separated by semicolons. Each command
to bc is either an expression, which it
evaluates, or a statement that affects the subsequent output. As a
short example, consider the following dialogue:
$ bc
1+2
3
100/7
14
scale=5
100/7
14.28571
sqrt(2)
1.41421
Most of this dialogue is self-explanatory; scale=5
indicates that subsequent calculations should be displayed correct
to 5 decimal places, and sqrt is a predefined
function that calculates the square root of its
argument. To use a function in bc , type the name of
the function followed by its argument enclosed in
parentheses. Thus to evaluate 'log base e of 10' the expression
would be l(10) (lower-case 'ell').
If the 'scale' is set to 0, no calculations are performed on
digits after the decimal point, and integer arithmetic is
performed. In this case the operator % will yield
integer remainder so that 11 % 3 would yield
2 . Some of the operators require bc to be
called with option -l ('library'). Trigonometric
functions assume you are working with radians (and not degrees),
and the exponential function e raises e (the base of
natural logarithms, 2.718...) to the power of its argument.
In bc you can use parentheses to group parts of an
expression together, so the expression
10 * (3 + 4)
would evaluate to 70 . You can use as many
parenthesised expressions as you like, provided you ensure that
each opening parenthesis is matched by a closing one - i.e. the
usual conventions in a programming language apply. Note that
multiplication and division take
precedence over addition and
subtraction, so that
1 + 3 * 4
is equivalent to
1 + (3 * 4)
and not to
(1 + 3) * 4
If in doubt about precedence, use parentheses
Worked example
Use bc to find the number of seconds in a
day.
Solution: The calculation we require is 24 x 60 x
60, and the dialogue that would follow is:
$ bc
24 * 60 * 60
86400
ctrl-D
Since bc takes input from standard input, to leave
bc you type ctrl-D on a line of its own. We
can also pipe expressions into bc , and
$ echo "1 + 2" | bc
would be a valid way of using bc , since the pipe
ensures that the standard output of echo becomes the
standard input to bc .
Worked example
Write a script to read in two numbers and display their
product.
Solution: Use read to input the
numbers, and then construct the expression that represents their
product using the * operator in bc . This
expression can then be passed to the standard input of
bc using echo .
echo Input two numbers: # Prompt the user ...
read N1 N2 # read in two numbers ...
echo "$N1 * $N2" | bc # pass their product to bc
|