Sunday, June 8, 2008

Bash float comparison - bc


Lets have a script to compare some float values.


$ cat floatcomp.sh
#!/bin/sh

array=(0.255 0.8569 5.356 3.8521)
max=0
len=${#array[*]}
i=0

while [ $i -lt $len ]
do
echo "$i: ${array[$i]}"
val=`echo "${array[$i]}" `
if [ $val -gt $max ]
then
max=$val
fi
let i++
done
echo "MAX IS => $max"


Running the script:


0: 0.255
./floatcomp.sh: line 12: [: 0.255: integer expression expected
1: 0.8569
./floatcomp.sh: line 12: [: 0.8569: integer expression expected
2: 5.356
./floatcomp.sh: line 12: [: 5.356: integer expression expected
3: 3.8521
./floatcomp.sh: line 12: [: 3.8521: integer expression expected
MAX IS => 0


HUH!! Where is the problem ? Got it, problem is with the if statement above we are using to compare two float values, we just can't compare float values like the ints and strings.
To make it work, we have to use "bc" command. Some of its sample uses are below:


$ echo "3.2 > 3.2" | bc
0

$ echo "3.2 > 3.4" | bc
0

$ echo "3.2 < 3.4" | bc
1


Note: Notice the output of the above comparisons.

Based upon it, we will modify our script, the if condition will be like this


if [ $(echo "$max < $val"|bc) -eq 1 ]

instead of

if [ $val -gt $max ]


So the script will look like this:

$ cat floatcomp1.sh
#!/bin/sh

array=(0.255 0.8569 5.356 3.8521)
max=0
len=${#array[*]}
i=0

while [ $i -lt $len ]
do
echo "$i: ${array[$i]}"
val=`echo "${array[$i]}" `
if [ $(echo "$max < $val"|bc) -eq 1 ]
then
max=$val
fi
let i++
done
echo "MAX IS => $max"


The output:

$ ./floatcomp1.sh
0: 0.255
1: 0.8569
2: 5.356
3: 3.8521
MAX IS => 5.356

3 comments:

Zdenek said...

great! thank you.

Jadu Kumar Saikia said...

@Zdnek, :-)

Micael999 said...

I am not a shell expert, but I thought of an alternative solution:

Sort the two numbers and get the top or tail (depending which one you want ) then compare it against the previous one but just to see if they are different (as strings), if so, you have acomplished the concept of greater than or less than

© Jadu Saikia www.UNIXCL.com