#21: The command line calculator bc
Performing calculations on the command line is very handy and bc
is the tool which does it for you. Also bash can do some calculation stuff, but that's not very intuitive. For instance
echo $[4*4]
calculates 4*4
. That stills looks easy, but as soon as you want to perform more complex calculations, this becomes a hassle. Bash is built for different things than calculation and so bc
is the better choice. It can do much more for you and its syntax is ways easier.
There are three ways to use bc
. The first is to use files. Write your bc
script into a file an then call
bc file
Use -q
to suppress the header of bc
. The second way is to use STDIN:
echo '1+2*3/4' | bc
and last but not least the third way is the interactive mode. Just run bc
and you get a shell-like prompt where you can insert your operations. Quit bc
by typing quit
and hitting enter.
It's up to your needs, which way you choose, there is no difference in functionality.
As you've already seen: basic arithmetic operations can be done with the operators +
, -
, *
and /
. But there's much more. You can, e.g., calculate the square root:
sqrt(x)
where x
is any number. The syntax of bc
is very C-like. Therefore you can also assign values to variables:
var=123
print var
You can also print strings to the screen:
print "Hello World\n"
There are also some special variables. For instance scale
:
scale=10
That sets the decimals form default 0 to 10. Examine the difference with
10/3
scale=10
10/3
The first line only generates 3
, the third one 3.3333333333
. Two other important special variables are ibase
and obase
, which define the number system; the default is 10 (decimal system). ibase
specifies the input number system and obase
the output number system. With these variables you can, e.g., convert hex digits to binary:
ibase=16
obase=2
F
Output is: 1111
(binary for hex F
).
bc
also let's you define functions like in any normal programming language. The language construct for this is define
:
define by2(x) { return x*2 }
You can now call this function:
by2(6)
The output is 12
.
Also conditions and loops are possible:
while (var < 5) {
++var
}
print var
if (by2(4) < 10) {
print "Foobar\n"
}
bc
also has some pre-defined functions for basic math operations. These are s(x)
for the sine, c(x)
for the cosine, a(x)
for the arctangent, l(x)
for the natural logarithm, e(x)
for raising the Euler constant to the power of x
and j(n, x)
for the Bessel function. These functions are all available when executing bc
with the -l
parameter, which loads the particular math library.
This is all very useful, but one thing has always bothered me is the precision of irrational numbers. bc
obviously does a pretty bad job on approximating these numbers. If I execute the following
l(e(3))
I always get 2.99999999999999999999 instead of 3. That's the same if I, e.g., want to calculate the cube root of, let's say, 8:
e(l(8)/3)
There I get 1.99999999999999999998 instead of 2. I know, this behavior should be platform specific, but it should be possible to get nicer results here by automatically rounding periods. As yet I haven't found a way to make bc
handle this smarter. If you know one, please leave me a comment.
Learn more about bc
:
RT @reflinux: #Advent series "24 Short #Linux #Hints", day 21: The #command line #calculator #bc http://bit.ly/fwRlDO