When writing scripts in bash, sometimes we need to work with basic math functions. Like the trigonometric functions, square root, cube root, logarithms. Bash does not support floating point operations. This is where the problem is encountered, and we cannot write a math function of our own. There must be a way to do this, and yes. Bash supports redirections so we can feed the floating point computations and the math functions into some other program’s input who understands it. The program which can be used is the `bc`, which is an arbitrary precision calculator language. `bc` can do floating point operations, and also can do basic math functions. With `bash` and `bc` we can do the above. Continue reading to know how.

### Check

Before doing anything first check if `bc` is installed in your system.To check if `bc` is installed execute the following:

rpm -q bc

If it says package bc is not installed then you need to install it. To install `bc` just execute the following in `yum`.

yum -y install bc

### What’s the stuff

The main stuff is to simply write a string with `echo` and pipe it into the input of `bc`, and get the answer.

If we want to add two floating point numbers say 2.5 and 3.75, then simply the string *“2.5+3.75″* should be feed into the input of `bc` and you are done. Check out the example below:

echo "2.5+3.75" | bc 6.25

Above the first line shows the input to bash, and the second line is the output.

As now you have understood the basic trick, that is so simply feed in any arithmetic expression into a program’s input, who understands it, to get the answer from it, i will present some more examples.

### Examples

Now lets say you want to get a square root of a number (floating point), say *641* . The function of `bc` which performs square root is `sqrt`. And as we are performing a math function we need to tell `bc` to turn on its standard math library. This can be done just by including the `-l` switch to bc. So the command will be as below:

echo "sqrt(641)" | bc -l 25.31797780234432546177

Till now you should have guessed that we can also use the shell variables in the `echo` with double quotes to enable variable value. For example check the command sequence below:

x=215 echo "sqrt($x)" | bc -l

And yes now the command performs the square root of the variable “x” , which can be assigned whatever.

The below nano shell script performs floating point addition operation using `bc`.

#!/bin/bash echo "Enter a floating point number: " read a echo "Enter another floating point number: " read b echo "Addition: " echo "$a+$b" | bc

Integer powers of a floating point could be calculated with the “^” operator. Below *“a”* is a floating point and *“b”* is integer.

echo "$a^$b" | bc -l

So it is simple. Now some trigonometric functions. In `bc` the `s` is the sine function, `c` is the cos function, and the `a` is the arctangent function (atan). And as normal the angles are to be passed as radians, but we can always do a degree to radian conversion. So we have the basic two. The below shell script demonstrates the calculation of different trigonometric vales.

#!/bin/bash echo "Enter angle in degree: " read deg # Note: Pi calculation # tan(pi/4) = 1 # atan(1) = pi/4 and # pi = 4*atan(1) pi=`echo "4*a(1)" | bc -l` rad=`echo "$deg*($pi/180)" | bc -l` echo "$deg Degree = $rad Radian" echo "Sin($deg): " echo "s($rad)" | bc -l echo "Cos($deg): " echo "c($rad)" | bc -l echo "Tan($deg): " echo "s($rad)/c($rad)" | bc -l

The natural logarithmic function in `bc` is `l`. So to calculate natural logarithm and ten base logarithm we would do the following:

#!/bin/bash echo "Enter value: " read x echo "Natural Log: ln($x) :" echo "l($x)" | bc -l echo "Ten Base Log: log($x) :" echo "l($x)/l(10)" | bc -l

And similarly the exponential function could be implemented by calling the `e` function in `bc`.

You can adjust the precision of the value which the math functions calculate be assigning the decimal point accuracy in the `scale` variable within `bc`. For an example if you want square root of a number up to 2 decimal places, you should do as below, where *“x”* is the variable.

echo "scale=2;sqrt($x)" | bc -l

Note that it simply truncates the decimal places, so the scaled value is not the approximation but only truncated. For example 6.74536878161602073277 in 2 decimal places would be simple truncated to 6.74, and not 6.75

### More

And now you can write a function in `bc` syntax and also make it use. As presented below, a factorial function:

#!/bin/bash echo "Enter an integer: " read n # Below we define the factorial function in bc syntax fact="define f (x) { i=x fact=1 while (i > 1) { fact=fact*i i=i-1 } return fact }" # Below we pass the function defined above, and call it with n as a parameter and pipe it to bc factorial=`echo "$fact;f($n)" | bc -l` echo "$n! = $factorial"

Clearly any other functions written in `bc` syntax could be used

### Resources

Check out more functions and operators and all the details of `bc` by visiting the site here: http://www.gnu.org/software/bc/manual/html_mono/bc.html , and also check the man page and info pages by executing:

man bc info bc

Here’s a small tweak…

If you use ksh, you can use shell co-processes instead of spawning ‘bc -l’ multiple times.

—————————————————-

#!/bin/ksh

if [ $# -lt 1 ]; then

echo -n “Enter angle in degree: ”

read deg

else

deg=$1

fi

bc -l |&

print -p “4*a(1)”

read -p pi

echo pi = $pi

print -p “$deg*($pi/180)”

read -p rad

echo “$deg Degree = $rad Radian”

print -p “s($rad)”

read -p sin_degrees

echo “Sin($deg): $sin_degrees”

print -p “c($rad)”

read -p cos_degrees

echo “Cos($deg): $cos_degrees”

print -p “s($rad)/c($rad)”

read -p tan_degrees

echo “Tan($deg): $tan_degrees”

Its even great with ksh then, no need to spawn multi processes each line. This could be done in bash by assigning the whole bc syntax into a shell variable and then pass the whole var into bc’s input. Just as described in the last example of the post.

@h446log: Thanks for the great comment.

Pingback: fractions in linux

Pingback: [Praktikum SO] Referensi « Blog Iseng – Iseng Aja….. :)

bc is not relly useful; no numbers with expnents (e.g. 1.22e9), and, (notoriously)

echo “1/2″ | bc

gives 0, which is simply wrong, if one ever attended school.

I suggest to use

echo “” | awk “{ print 1/2}”

which gives 0.5, and supports the complete mathematical standard library.

Just use

bc -lto enable the standard math library and set the scale to 20, and you will get the correct answer.awkis also a good way.Thanks, your article was very helpful! :)

Nice to know it helped you, thanks for stopping by!

Thanks, your article was very helpful!

some how bc made the use of bash variables more complex, thought that is more helpfull to use awk than even when is less precise, the expansion of variables is possible and the line is less long and more readable when you don’t have the hardcoded values at the time you write an script

Other programs capable of floating point operations are fine as well. In case of bc, yes, constructing the script from bash variables seems a bit tricky and may be I would like to go with bc scripts. Although in actual application I use perl for scripting and for scientific computation octave and R. awk is not my game :D , may be you can post a sample awk script for similar floating point operations which can be used inside bash.

Thanks for visiting!