There are these occurrences when you need a calculation be a little more exact. Here is how you get this accomplished.
There are two important things shown in this section:
- How to do this computation
- How to invoke external commands and redirect their stdout into one of your variables.
I will revisit this example at a later point.
In order to work with rational and real numbers in a shell script we need bc as an additional command. You may call bc on the command line and use it for your ad hoc computations. Sometimes it’s just easier than grabbing the mouse to open the graphical instance of what once was our pocket calculator. bc is the arbitrary precision calculator language. So it probably will be capable of lots more than what I am showing here. Please refer to the man page using man bc
To begin with, I would like to repeat a few things, that actually should have been published before. As I am publishing this stuff out of order, the one or the other thing might not have been mentioned yet.
And now the sample script:
let dp=2 # decimal place
s_res=`echo $zahl1"/"$div | bc -l` # The result will be 314.066666666666666666
# The result is treated as a string
t1=`echo $s_res | cut -d "." -f 1` # Separate the number represented by the
# string into two parts
# take the integer part and assign it to t1
t2=`echo $s_res | cut -d "." -f2` # now take the second part and assign it to
# Now we deal with the value .06666666....
t3=`echo $t2 | cut -b 1-$dp` # cut of the first two bytes of t2
# here in this example we have two decimal
s_res=$t1$t3 # concatenate the two fields. The result
# is not yet rounded.
set n_res=$s_res # now it's a number
let r_pos=$dp+1 # The decimal position, we are using to
# round is one past the position, we want
# in our result.
# It is important that we think a little about rounding!
# Depending on the problem domain there are very specific rules on rounding.
# So before you start rounding you need to consult your client and preferably
# get a written specification from him/her.
let r_fig=`echo $t2 | cut -b $r_pos` # Now the number 6 is stored in r_fig
if [[ $r_fig -ge 5 ]] ; then # the rounding rule I am using here, is
let n_res=$n_res+1 # simple.
# in this example the value in n_res now
# is 31407
# Now we need to move the decimal point
end_res=`echo $n_res"/10^"$dp | bc -l` # by two positions
echo $end_res # yeah, this is it: 314.07000000000000000
Of course after this process, the result will be 314.07000000000000000 but in this script you have seen all steps to format it at your convenience.