Fixed calculations in Unix scripts

Although I've already shown you how to sum numbers up in bash, I only covered the bash way of doing it. I really like scripting with bash, but when it comes to calculations, there's quite a few important features missing from bash, and fixed point (thanks for the correction, Azrael Tod!) calculations is one of them. Fortunately, bc command comes as a standard in most Unix distros, and can be used for quite complex calculations.

Basic calculations with bc

bc is a very simple command. It takes standard input as an expression and then evaluates this, performing all the necessary calculations and showing you the result. Thus, to quickly sum numbers up or get a result of some other calculation, simply echo the expression and then pipe it out to the bc command:

ubuntu$ echo "1+2" | bc

Now, in scripts your calculations with bc are done quite similarly to what we did in bash. Here's an example:

ubuntu$ NUMBER1=1
ubuntu$ NUMBER2=2
ubuntu$ SUM=$(echo "$NUMBER1+$NUMBER2"| bc)
ubuntu$ echo $SUM

I told you these calculations would be basic, right? Now onto the more interesting stuff!

Fixed point calculations with bc

Most people learn about bash math limitations when they attempt to do a simple calculation but can't get the current answer with fixed point values. By default, all the operations happen with integers, and that's what you would get:

ubuntu$ echo "1/2" | bc

Now, if you expect 0.5 to be the result of dividing 1 by 2, you need to explain it to bc, because by default it doesn't show you any fractional part of the number.

The way you do this is quite simple: all you have to do is specify the number of digits you'd like to see  after the radix point of your result. For example, if I set this number to 5, I'll get bc to output the result of my calculation with 5 digits after the radix point. The special keyword to convey this intention to the bc command is called scale. Just specify the scale value and separate it from the rest of your expression by the semicolon sign:

ubuntu$ echo "scale=5; 1/2" | bc

Here's another example:

ubuntu$ echo "scale=5; 0.16*10.79" | bc

Hope this answers your question! bc command is very powerful, so I'll definitely have to revisit it again in the future. For now though, enjoy the fixed point calculations and be sure to ask questions if you think I can help!

See also:

  • uhm.. bc does fixed-point-math, not float.
    This explains why you have to set where the point is placed and gives _exact_ results (as opposed to FP, where every number is calculated through exponential calculations)

    if you dont understand what i mean you could simply try to add very small numbers to a big one.
    If you got the numbers right, you wont see any change in the big number, this means whateveroften you add a to b you wont see any change in b.
    …even if a multiplicated by the number of additions (before you add it) would be a lot bigger then b.

  • Thanks for the correction, Dr Tod!

    I completely mixed the meanings, and thanks to you I have just fixed the post.

    Please let me know if there's a better way of explaining the topic!