# Comparison of decimal numbers in bash

My search this morning was about how could I compare two decimal numbers in bash, and I came to this answser: How to compare to floating point number in a shell script. This one, however, doesn't include this answer here:

``````\$ [[ ((3.56 < 2.90)) ]]; echo \$?
1
\$ [[ ((3.56 < 4.90)) ]]; echo \$?
0
``````

Considering that answer has been downvoted, and it looks some kind of unusual bashism, is this arithmetic evaluation trustworthy for accuracy?

`bash` does not understand floating point numbers.
Quoting `bash` manual page, section ARITHMETIC EVALUATION:

Evaluation is done in fixed-width integers […].

So `((3 < 4))` or `((3 < 2))` are actually correct arithmetic expressions. You can type the following:

``````\$ echo "\$((3 < 4)) -- \$((3 < 2))"
``````

output: `1 -- 0`

But `\$ echo \$((3.3 < 3.6))` will return a syntax error message. In your example, you are actually comparing strings. Hence some example:

``````\$ [[ ((3.56 < 04.90)) ]]; echo \$?
``````

output: `1`

• Both answers are awesome, but I'm choosing yours because of the example, which made me realize what could go wrong :) Jun 15, 2014 at 4:16

Inside `[[...]]` `<` is for string comparison.

So `[[ 3.56 < 2.90 ]]` or `[[ (3.56 < 2.90) ]]` or `[[ ((3.56 < 2.90)) ]]` or `[[ (((3.56 < 2.90))) ]]`... is just comparing the `3.56` string with the `2.90` string lexically (and lexically, `3` is greater than `10` for instance).

For integer comparison, it's `[[ 3 -lt 2 ]]` or `(( 3 < 2 ))`. If you want floating point comparison, you need `ksh93`, `zsh` or `yash` or an external utility like `awk` or `perl`; `bash` can't do it.

You could for instance define a function like:

``````compare() (IFS=" "
exec awk "BEGIN{if (!(\$*)) exit(1)}"
)
``````

Which you could use for instance like:

``````if compare '1.5*10 < 1e3'; then
echo less
fi
``````

Or even for that matters:

``````if compare '"bar" < "foo"'...
``````

to do string comparisons.

Do not pass uncontrolled externally provided data to that `compare` function as it would constitute a command injection vulnerability (the data is interpreted as `awk` code, `awk` can run commands with its `system()` for instance).

• To illustrate the importance of the difference between string vs. numeric comparison, consider that `[[ 11.56 < 2.90 ]]` (and `[[ ((11.56 < 2.90)) ]]` and...) is true, because "1" comes before "2" in ascii sorting order. Jun 15, 2014 at 0:51
• @GordonDavisson, yes, and `[[ 0.1 < 1e-20 ]]` and whether `[[ -2 < 1 ]]` is locale-dependent. Jun 15, 2014 at 9:31
• `[[ 3 -lt 2 ]]` uses conditional expression, and `(( 3 < 2 ))` uses arithmetic expression. When comparing two integers, can these two methods always be used interchangeably? If yes, why does Bash have two methods rather than one?
– Tim
Apr 23, 2016 at 21:46