bc: number crunching in the terminal

There are many choices to consider when we want to perform arithmetical operations in a terminal. Probably the safest approach is to just use Python, especially with the NumPy library. But there is no need to call Python if we just want to perform simple maths. For example, say we want to compute the square root of two.

The bc command is one out of many options to achieve it. Here is a way to compute it:

$ echo "sqrt(2.)" | bc -l
1.41421356237309504880

The -l flag is called to give the result as a floating point number, otherwise it would just give the integer part, 1. But what if we want just two decimal positions? Then run

$ echo "scale=2; sqrt(2.)" | bc
1.41

If you need to perform several calculations, don't use scale until the last one, otherwise an unnecessary rounding error would be accumulated. In fact, there is no point losing precision in your variables. It is much better to round when printing the result. For example:

$ result=$(echo "sqrt(2.)" | bc -l)
$ printf "%.2f\n" "$result"
1.41

A little challenge: print the square roots of n for n going from 0 to 10, using printf to round the output to 4 decimals.

$ for i in {1..10}; do printf "%.4f\n" "$(echo "sqrt($i)" | bc -l)"; done
1.0000
1.4142
1.7321
2.0000
2.2361
2.4495
2.6458
2.8284
3.0000
3.1623

Another challenge: compare two float numbers in a script. We cannot use something like

if [ "$a$ -lt "$b$ ]

unless a and b are integer numbers. So we can use bc to build the expression a-b, and then

#! /bin/sh
a=$(echo "sqrt(2)" | bc -l)
b=$(echo "sqrt(3)" | bc -l)
test=$(echo "$a - $b >0" | bc -l)
if [ "$test" -eq 1 ]; then
   echo "$a is greater than $b"
else
   echo "$a is smaller than $b"
fi

This script will give

1.41421356237309504880 is smaller than 1.73205080756887729352

Among many features, we can even define variables in it:

$ echo "a = sqrt(2); b = sqrt(3); a * b" | bc -l
2.44948974278317809818

This tool is included in the wonderfully small BusyBox binary. An example of how to call bc from it:

$ echo "sqrt(2)" | /usr/bin/busybox bc -l
1.41421356237309504880

In short, bc is a great tool for scripts and commands where you need floating-precission arithmetics. Check out its great documentation page.