This is a brief post on quick ways to perform floating point arithmetic in the GNU Bourne Again Shell (BASH), either at the command prompt or in a shell script. It is partially a followup to the post Ten Great Quick Calculators for Computer Users and overlaps some of the content in this previous post.
The Bourne Again Shell, or bash, is the default command line processor (shell) for Mac OS X, the cygwin environment on MS Windows, and many other Unix and Unix-like systems. Especially if you work with numbers, you may want to perform quick floating point arithmetic at the command prompt (shell) or in shell scripts. This post covers five ways to perform floating point arithmetic in bash: the bc arbitrary precision calculator language, the awk pattern scanning and processing language, the perl programming language, the python programming language, and the ruby programming language.
Integer Only Arithmetic in BASH
Note: One can perform integer arithmetic and integer arithmetic alone (no floating point) by using the Unix expr utility and the bash $[N op M] syntax where N and M are any integers and op is any arithmetic operator (+, -, *, /). For example:
John@John-HP ~ $ expr 1 + 2 3 John@John-HP ~ $ echo $[1 + 2] 3
These integer-only arithmetic methods were described more fully in the previous post Ten Great Quick Calculators for Computer Users.
Five Ways to Perform Floating Point Arithmetic in BASH
(1) BC
The following commands show how to perform floating point arithmetic (addition, subtraction, multiplication, and division) at the bash shell prompt using the bc arbitrary precision calculator language. Note the need to escape the multiply operator * with a backslash or enclose the arithmetic expression in single quotes. Note the use of the backtick myvar=`command` syntax to assign the results of the arithmetic to a bash variable.
Note that there should be no space between the variable name and the equal sign in the assignment, otherwise an error occurs.
John@John-HP ~ $ echo 1.1 + 2.2 | bc -l 3.3 John@John-HP ~ $ echo 1.1 - 2.2 | bc -l -1.1 John@John-HP ~ $ echo 1.1 * 2.2 | bc -l 1.1 (THIS IS WRONG!!!!) John@John-HP ~ $ echo 1.1 \* 2.2 | bc -l 2.42 (THIS IS RIGHT!!!) John@John-HP ~ $ echo '1.1 * 2.2' | bc -l 2.42 (THIS IS RIGHT!!!) John@John-HP ~ $ echo '1.1 / 2.2' | bc -l .50000000000000000000 John@John-HP ~ $ myvar=`echo '1.1 / 2.2' | bc -l` John@John-HP ~ $ echo $myvar .50000000000000000000
(2) AWK
The following commands show how to perform floating point arithmetic (addition, subtraction, multiplication, and division) at the bash prompt using the awk pattern scanning and processing language. The AWK operators and functions for raising a number to a power (**,^), the square root (sqrt(x)), the natural logarithm (log(x)), the sine function (sin(x)), cosine function (cos(x)), and the arctangent (atan2(y,x)) are also shown. Note the use of the backtick myvar=`command` syntax to assign the results of the arithmetic to a bash variable. AWK has the advantage that it is very old and is almost always available on Unix and Unix-like systems.
Note that there should be no space between the variable name and the equal sign in the variable assignment.
John@John-HP ~ $ echo - | awk '{print 1.1 + 2.2}' 3.3 John@John-HP ~ $ echo - | awk '{print 1.1 - 2.2}' -1.1 John@John-HP ~ $ echo - | awk '{print 1.1 * 2.2}' 2.42 John@John-HP ~ $ echo - | awk '{print 1.1 / 2.2}' 0.5 John@John-HP ~ $ echo - | awk '{print 1.1 ^ 2.2}' 1.23329 John@John-HP ~ $ echo - | awk '{print 1.1 ** 2.2}' 1.23329 John@John-HP ~ $ echo - | awk '{print log(10.0)}' 2.30259 John@John-HP ~ $ echo - | awk '{print sqrt(2.0)}' 1.41421 John@John-HP ~ $ echo - | awk '{print sin(1.0)}' 0.841471 John@John-HP ~ $ echo - | awk '{print cos(1.0)}' 0.540302 John@John-HP ~ $ echo - | awk '{print atan2(1.0, 1.0)}' 0.785398 John@John-HP ~ $ myvar=`echo - | awk '{print 1.1 + 2.2}'` John@John-HP ~ $ echo $myvar 3.3
(3) PERL
The following commands show how to perform floating point arithmetic (addition, subtraction, multiplication, and division) using the Perl programming language at the bash prompt. Note the use of the backtick myvar=`command` syntax to assign the results of the arithmetic to a bash variable. Perl is widely used and almost always already installed on Unix and Unix-like systems.
Note that there should be no space between the variable name and the equal sign in the variable assignment.
John@John-HP ~ $ perl -e 'print 1.1 + 2.2' 3.3 John@John-HP ~ $ perl -e 'print 1.1 - 2.2' -1.1 John@John-HP ~ $ perl -e 'print 1.1 * 2.2' 2.42 John@John-HP ~ $ perl -e 'print 1.1 / 2.2' 0.5 John@John-HP ~ $ myvar2=`perl -e 'print 1.1 + 2.2'` John@John-HP ~ $ echo $myvar2 3.3
(4) PYTHON
The following commands show how to perform floating point arithmetic (addition, subtraction, multiplication, and division) using the Python programming language at the bash prompt. Note the use of the backtick myvar=`command` syntax to assign the results of the arithmetic to a bash variable. Python is widely used and frequently already installed on Unix and Unix-like systems.
Note that there should be no space between the variable name and the equal sign in the variable assignment.
John@John-HP ~ $ python -c 'print 1.1 + 2.2' 3.3 John@John-HP ~ $ python -c 'print 1.1 - 2.2' -1.1 John@John-HP ~ $ python -c 'print 1.1 * 2.2' 2.42 John@John-HP ~ $ python -c 'print 1.1 / 2.2' 0.5 John@John-HP ~ $ myvar3=`python -c 'print 1.1 + 2.2'` John@John-HP ~ $ echo $myvar3 3.3
(5) RUBY
The following commands show how to perform floating point arithmetic (addition, subtraction, multiplication, and division) using the Ruby programming language at the bash prompt. Note the use of the backtick myvar=`command` syntax to assign the results of the arithmetic to a bash variable. Ruby is widely used and sometimes already installed on Unix and Unix-like systems.
Note that there should be no space between the variable name and the equal sign in the variable assignment.
John@John-HP ~ $ ruby -e 'print 1.1 + 2.2' 3.3 John@John-HP ~ $ ruby -e 'print 1.1 - 2.2' -1.1 John@John-HP ~ $ ruby -e 'print 1.1 * 2.2' 2.42 John@John-HP ~ $ ruby -e 'print 1.1 / 2.2' 0.5 John@John-HP ~ $ myvar4=`ruby -e 'print 1.1 + 2.2'` John@John-HP ~ $ echo $myvar4 3.3
These same commands to perform floating point arithmetic can be included in Bourne Again Shell (bash) scripts.
Conclusion
There are at least five ways to perform floating point arithmetic under the Unix or GNU Bourne Again Shell (bash), either at the command prompt or in shell scripts. These are the bc arbitrary precision calculator language, the awk pattern scanning and processing language, the perl programming language, the python programming language, and the ruby programming language.
AWK is most likely to be preinstalled on a Unix or Unix-like system, followed by BC and PERL. Python is now fairly common although still not as common as PERL. RUBY is becoming fairly common, but it is still not as common as Python in the author’s experience. BC has the special advantage that it is an arbitrary precision calculator whereas the others are usually 32 or 64 bit precision floating point by default.
© 2012 John F. McGowan
About the Author
John F. McGowan, Ph.D. solves problems using mathematics and mathematical software, including developing video compression and speech recognition technologies. He has extensive experience developing software in C, C++, Visual Basic, Mathematica, MATLAB, and many other programming languages. He is probably best known for his AVI Overview, an Internet FAQ (Frequently Asked Questions) on the Microsoft AVI (Audio Video Interleave) file format. He has worked as a contractor at NASA Ames Research Center involved in the research and development of image and video processing algorithms and technology. He has published articles on the origin and evolution of life, the exploration of Mars (anticipating the discovery of methane on Mars), and cheap access to space. He has a Ph.D. in physics from the University of Illinois at Urbana-Champaign and a B.S. in physics from the California Institute of Technology (Caltech). He can be reached at jmcgowan11@earthlink.net.
Wow! You had read 5 manuals! Great work!
A short script to keep arithmetic simple:
#!/bin/bash
echo $1 | bc -l
I called this script, which is based on your first approach, m (for math). I added its location to my path, so anytime I want to do basic calculations from the command line, I can invoke it simply by typing, for example, “m 22/7” or “m 6\*9”.
(NB: The way I wrote it, using $1 in the script, your entire expression has to be one command-line argument, so make sure to put the expression in quotes if you want spaces inside it.)
Just a snippet of code from me. It took me forever to work it out, but here is an alternative.
With my code, I wanted to convert from degrees to Radians. And here is the line of code
Rad_Theta1=`echo “0.0174532925*$Deg_Theta1” | bc`
where Deg_Theta1, is entered by the user.
0.0174…. is the degree to radian constant
Thanks Dr. McGowan, this is a good summary of math. My team’s working on an AWK math stats tool for piping data, such as calculating sum, mean, var, skew, kurt, etc. Could we interest you in taking a look at it and possibly blogging about it? It’s called Num and it’s at https://www.numcommand.com
If you need to compare various floating point numbers don’t forget sort! The GNU sort atleast supports double precision floating point math, eg:
echo -e ‘0.00002\n0.2\n1.4\n1.00000003’ | sort -n
0.00002
0.2
1.00000003
1.4
x=1.2
y=2.3
echo – | awk ‘{print $x ^ $y}’
returns 1
and NONE of these is in bash. Even the expr example is not in bash
🙁
This would be a bash example of integer match
echo $((1 + 1 ))
2
In reply to @Ben; let’s make bash float:
x=11.1
y=22.2
for (( prec=0; prec<${#x}; prec++)); do [[ "${x:$prec:1}" == "," ]] && break; done; printf "%.${prec}f\n" "$(( ${x//\.} * ${y//\.} ))e-${prec}"
2.4642
DISCLAIMER: only works when both variables use the same decimal base