Fast Bash Math





7
Date Submitted Sat. Sep. 9th, 2006 12:47 AM
Revision 1 of 1
Beginner smallshellscript
Tags bash | sh | shell
Comments 2 comments
A lot of time shell scripts need to do some sort of math. Bash's innability to do floating point arithmatic has lead to some pretty neat workarounds, often times these workarounds are slow. If you need a lot of calculations done with speed, you'll find this snippet useful

#!/bin/bash
sum=$(( 4 + 4 ))
echo $sum

difference=$(( 4 - 4 ))
echo $difference

product=$(( 4 * 4 ))
echo $product

quotient=$(( 4 / 4 ))
echo $quotient

remainder=$(( 4 % 4 ))
echo $remainder
 

sum=$(echo "scale=3; 4 + 4" | bc)
#This can also do more complicated math.
sum=$(echo "scale=3; "2 * ( 4 + 4 ) / 4" | bc)
 

22.22 48.583
24.1 24.594
29.389 283.298
294.293 29.1
...
92.2 19.494
 

#!/bin/bash
##
# Make some fifos we can connect to.
##
mkfifo /tmp/bc.in
mkfifo /tmp/bc.out
##
# Attach file descriptors to those fifos.
##
exec 7<>/tmp/bc.in
exec 8<>/tmp/bc.out

##
# Start a single bc process in background and connect our fds to
# it's stdin, stdout, stderr we can use to do all of our math. We can
# do this because bc is an interpreter, with it's own shell.  Using
# these same methods we can do inline perl/php/python, etc in
# bash.
##
bc 0<&7 1>&8 2>&8 &

while read numerator denominator
do
  echo "scale=5; $numerator / $denominator" >&7
  read quotient <&8
  # bc errors have ':' in them somewhere.
  if [ "$quotient" != "${quotient//:/}" ; then
      echo "Error: $quotient"
  else
      echo "Answer of $numerator / $denominator is $quotient."
  fi
done

##
# Shutdown our bc process
##
echo "quit" >&7
##
# Close down our file descriptors.
##
exec 7>&-
exec 7<&-
exec 8>&-
exec 8<&-
 

John Anderson

Comments

Comments correction
Tue. Aug. 14th, 2007 9:10 AM    Newbie jbachman
Comments mkfifo - any sideeffects?
Sun. Aug. 19th, 2007 3:54 PM    Newbie nhed

Voting