¿Cómo puedo comparar dos números de punto flotante en Bash?
Estoy intentando comparar dos números de punto flotante dentro de un script Bash. Tengo dos variables, por ejemplo
let num1=3.17648e-22
let num2=1.5
Ahora sólo quiero hacer una comparación simple de estos dos números:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
Lamentablemente, tengo algunos problemas con el tratamiento correcto del número 1, que puede tener el "formato electrónico".
Más convenientemente
Esto se puede hacer más convenientemente usando el contexto numérico de Bash:
if (( $(echo "$num1 > $num2" |bc -l) )); then
…
fi
Explicación
La canalización del comando básico de la calculadora bc
devuelve 1 o 0.
La opción -l
es equivalente a --mathlib
; Carga la biblioteca matemática estándar.
Encerrar la expresión completa entre doble paréntesis (( ))
traducirá estos valores a verdadero o falso, respectivamente.
Por favor, asegúrese de que el bc
paquete básico de la calculadora esté instalado.
Advertencia: la notación exponencial debe escribirse como *10^
; no E
, ni e
.
Por ejemplo:
$ echo "1*10^3==1000" |bc
1
Mientras
$ echo "1E3==1000" |bc
0
Aquí se analizan las estrategias para superar esta bc
limitación .
Bash solo maneja matemáticas de números enteros, pero puedes usar el bc
comando de la siguiente manera:
$ num1=3.17648E-22
$ num2=1.5
$ echo $num1'>'$num2 | bc -l
0
$ echo $num2'>'$num1 | bc -l
1
Tenga en cuenta que el signo del exponente debe estar en mayúscula.
Es mejor usar AWK para matemáticas no enteras. Puede utilizar esta función de utilidad Bash:
numCompare() {
awk -v n1="$1" -v n2="$2" 'BEGIN {printf "%s " (n1<n2?"<":">=") " %s\n", n1, n2}'
}
Y llámalo como:
numCompare 5.65 3.14e-22
5.65 >= 3.14e-22
numCompare 5.65e-23 3.14e-22
5.65e-23 < 3.14e-22
numCompare 3.145678 3.145679
3.145678 < 3.145679