Division in script and floating-point

Solution 1:

You could use the bc calculator. It will do arbitrary precision math using decimals (not binary floating point) if you set increease scale from its default of 0:

$ m=34
$ bc <<< "scale = 10; 1 - (($m - 20) / 34)"
.5882352942

The -l option will load the standard math library and default the scale to 20:

$ bc -l <<< "1 - (($m - 20) / 34)"
.58823529411764705883

You can then use printf to format the output, if you so choose:

printf "%.3f\n" "$(bc -l ...)"

Solution 2:

Bash does not do floating point math. You can use awk or bc to handle this. Here is an awk example:

$ m=34; awk -v m=$m 'BEGIN { print 1 - ((m - 20) / 34) }'
0.588235

To assign the output to a variable:

var=$(awk -v m=$m 'BEGIN { print 1 - ((m - 20) / 34) }')

Solution 3:

Teach bash e.g. integer division with floating point results:

#!/bin/bash

div ()  # Arguments: dividend and divisor
{
        if [ $2 -eq 0 ]; then echo division by 0; exit; fi
        local p=12                            # precision
        local c=${c:-0}                       # precision counter
        local d=.                             # decimal separator
        local r=$(($1/$2)); echo -n $r        # result of division
        local m=$(($r*$2))
        [ $c -eq 0 ] && [ $m -ne $1 ] && echo -n $d
        [ $1 -eq $m ] || [ $c -eq $p ] && echo && return
        local e=$(($1-$m))
        c=$(($c+1))
        div $(($e*10)) $2
}  

    result=$(div 1080 633)                  # write to variable
    echo $result

    result=$(div 7 34)
    echo $result

    result=$(div 8 32)
    echo $result

    result=$(div 246891510 2)
    echo $result

    result=$(div 5000000 177)
    echo $result

Output:

    1.706161137440
    0.205882352941
    0.25
    123445755
    28248.587570621468