views:

195

answers:

2

I had to do a division in shell script and the best way was:

result1=`echo "scale=3; ($var1 / $total) * 100"| bc -l`
result2=`echo "scale=3; ($var2 / $total) * 100"| bc -l`

but I want to compare the values of $result1 and $result2

Using if test $result1 -lt $result2 or if [ $result1 -gt $result2 ] didn't work :(

Any idea how to do that?

+1  A: 

You can compare floating-point numbers using expr(1):

: nr@yorkie 3724 ; expr 3.1 '<' 3.3
1
: nr@yorkie 3725 ; expr 3.1 '<' 3.09
0

You can also have bc do the comparisons as well as the calculations:

if [ "$(echo $result1 '<' $result2 | bc -l)" -eq 1 ];then ... fi

Finally, ksh93 can do arithmetic evaluation $(($result1 < $result2)) with floating-point numbers, although bash cannot.

Norman Ramsey
` if [ "$(echo $resutl1 '>' $result2 | bc -l)" -eq 1 ];then ` works for me :)
Reem
A: 

note that you've gotta be a bit careful when dealing with floating point numbers and if you are testing for equality you really want to decide on some precision and then compare using that. Something like:

if (abs(x1-x2) < 0.0001) then equal # pseudo-code

the reason being that with computers we're dealing with limited-precision binary fractions not true mathematical reals. Limiting the precision in bc with the scale=3 will have this effect.

I'd also advise against trying to do this stuff in shell script. It's not that you can't do it but you'll have to fork off lots of little sub commands to do the tricky bits and that's slow to execute and generally a pain to write - you spend most of your time trying to get the shell to do what you want rather than writing the code you really want. Drop into a more sophisticated scripting language instead; my language of choice is perl but there are others. like this...

echo $var1 $var2 $total | perl -ne 'my ($var1, $var2, $tot) = split /\s+/; if ($var1/$tot == $var2/$tot) { print "equal\n"; }'

also note that you're dividing by the same value ($total in your question) so the whole comparison can be done against the numerators (var1 and var2) provided $total is positive

Nick