Floating-point arithmetic in UNIX shell script Floating-point arithmetic in UNIX shell script unix unix

Floating-point arithmetic in UNIX shell script


I believe you should use : bc

For example:

echo "scale = 10; 123.456789/345.345345" | bc

(It's the unix way: each tool specializes to do well what they are supposed to do, and they all work together to do great things. don't emulate a great tool with another, make them work together.)

Output:

.3574879198

Or with a scale of 1 instead of 10:

echo "scale = 1; 123.456789/345.345345" | bc

Output:

.3

Note that this does not perform rounding.

I highly recommand switching to awk if you need to do more complex operations, or perl for the most complex ones.

ex: your operations done with awk:

# create the test file:printf '1.5493482,3.49384,33.284732,23.043852,2.2384,12.1,13.4,...\n' > somefileprintf '3.384,3.282342,23.043852,2.23284,8.39283,14.1,15.2,...\n'    >> somefile# do OP's calculations (and DEBUG print them out!)awk -F',' '   # put no single quote in here... even in comments! you can instead print a: \047    # the -F tell awk to use "," as a separator. Thus awk will automatically split lines for us using it.    # $1=before first ","  $2=between 1st and 2nd ","  ... etc.    function some_awk_function_here_if_you_want() {  # optionnal function definition         # some actions here. you can even have arguments to the function, etc.         print "DEBUG: no action defined in some_awk_function_here_if_you_want yet ..."    }        BEGIN      {  rem="Optionnal START section. here you can put initialisations, that happens before the FIRST file-s FIRST line is read"    }        (NF>=8)    {  rem="for each line with at least 8 values separated by commas (and only for lines meeting that condition)"                  calc1=($2 - $7)                  calc2=($3 * $2)                  calc3=($2 - $1)                  calc4=($2 + $8)                  # uncomment to call this function :(ex1): #  some_awk_function_here_if_you_want                  # uncomment to call this script:(ex2): # cmd="/path/to/some/script.sh \"" calc1 "\" \"" calc2 "\" ..." ; rem="continued next line"                  # uncomment to call this script:(ex2): # system(cmd); close(cmd)                   line_no=(FNR-1) # ? why -1? .  FNR=line number in the CURRENT file.   NR=line number since the beginning (NR>FNR after the first file ...)                  print "DEBUG: calc1=" calc1 " , calc2=" calc2 " , calc3=" calc3 " , calc4=" calc4 " , line_no=" line_no                  print "DEBUG fancier_exemples: see man printf for lots of info on formatting (%...f for floats, %...d for integer, %...s for strings, etc)"                  printf("DEBUG: calc1=%d , calc2=%10.2f , calc3=%s , calc4=%d , line_no=%d\n",calc1, calc2, calc3, calc4, line_no)    }    END        {  rem="Optionnal END section. here you can put things that need to happen AFTER the LAST file-s LAST line is read"    }      '  somefile # end of the awk script, and the list of file(s) to be read by it.


What about this?

calc=$(echo "$String2 + $String8"|bc)

This will make bc to add the values of $String2 and $String8 and saves the result in the variable calc.


If you don't have the "bc" you can jast use 'awk' :

calc=$(echo 2.3 4.6 | awk '{ printf "%f", $1 + $2 }')