How to compare two floating-point values in shell script How to compare two floating-point values in shell script shell shell

How to compare two floating-point values in shell script


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

: nr@yorkie 3724 ; expr 3.1 '<' 3.31: nr@yorkie 3725 ; expr 3.1 '<' 3.090

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.


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


Posting a new answer since I cannot yet comment...

@Norman Ramsey's answer is not quite accurate:

  • expr will perform an integer or string comparison, not a floating-point comparison.
    Here's what the man page says:

    expr1 {=, >, >=, <, <=, !=} expr2

    Return the results of integer comparison if both arguments are integers; otherwise, returns the results of string comparison using the locale-specific collation sequence.

    (just try expr 8.9 '<' 10 and get 0 where it should be 1).

  • bcworks great, but isn't always installed.


So another alternative is using perl -e:

  • perl -e 'print expression' will print 1 if expression is true and nothing (empty string) otherwise.

    e.g. perl -e 'print 8.9 < 10' - prints "1", while perl -e 'print 2>4' prints nothing.

  • And when used in if statement:

    if [ $(perl -e "print $result1 < $result2") ];then ... fi