Comparison of decimal numbers in bash

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).


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