Quiero comparar dos números de coma flotante en un script de shell. El siguiente código no funciona:
#!/bin/bash
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo $min
shell
shell-script
arithmetic
RIchard Williams
fuente
fuente
0.5
y0.06
). Será mejor que use una herramienta que ya entienda la notación decimal.1.00000000000000000000000001
es mayor que2
.Bash no entiende la aritmética de coma flotante. Trata los números que contienen un punto decimal como cadenas.
Use awk o bc en su lugar.
Si tiene la intención de hacer muchas operaciones matemáticas, probablemente sea mejor confiar en python o perl.
fuente
Puede usar el paquete num-utils para manipulaciones simples ...
Para matemáticas más serias, vea este enlace ... Describe varias opciones, por ejemplo.
Un ejemplo de
numprocess
Aquí hay un
bash
truco ... Agrega los primeros 0 al entero para hacer que una comparación de cadena de izquierda a derecha sea significativa. Este código particular requiere que tanto min como val tengan un punto decimal y al menos un dígito decimal.salida:
fuente
Para cálculos simples sobre números de coma flotante (+ - * / y comparaciones), puede usar awk.
O, si tiene ksh93 o zsh (no bash), puede usar la aritmética integrada de su shell, que admite números de coma flotante.
Para cálculos de coma flotante más avanzados, busque bc . Realmente funciona en números de punto de fijación de precisión arbitraria.
Para trabajar en tablas de números, busque R ( ejemplo ).
fuente
Usar ordenación numérica
El comando
sort
tiene una opción-g
(--general-numeric-sort
) que se puede usar para comparaciones en<
"menor que" o>
"mayor que", encontrando el mínimo o el máximo.Estos ejemplos son encontrar el mínimo:
Admite notación electrónica
Funciona con notación bastante general de números de coma flotante, como con la notación E
Tenga en cuenta que
E-10
, haciendo el primer número0.000000001245
, de hecho menor que10.35
.Se puede comparar con el infinito
El estándar de coma flotante, IEEE754 , define algunos valores especiales. Para estas comparaciones, las interesantes son
INF
para el infinito. También está el infinito negativo; Ambos son valores bien definidos en el estándar.Para encontrar el uso máximo
sort -gr
lugar desort -g
invertir el orden de clasificación:Operación de comparación
Para implementar la
<
comparación ("menor que"), de modo que pueda usarse enif
etc., compare el mínimo con uno de los valores. Si el mínimo es igual al valor, comparado como texto , es menor que el otro valor:fuente
a == min(a, b)
es lo mismo quea <= b
. Vale la pena señalar que esto no verifica estrictamente menos que sin embargo. Si desea hacer eso, debe verificara == min(a, b) && a != max(a, b)
, en otras palabrasa <= b and not a >= b
Simplemente use
ksh
(ksh93
precisamente) ozsh
, que ambos admiten de forma nativa la aritmética de coma flotante:Editar: Lo siento, me perdí
ksh93
ya fue sugerido. Mantener mi respuesta solo para dejar en claro que el script publicado en la pregunta de apertura se puede usar sin cambios fuera del interruptor de shell.Edit2: tenga en cuenta que
ksh93
requiere que el contenido variable sea coherente con su configuración regional, es decir, con una configuración regional en francés, se debe utilizar una coma en lugar de un punto:Una solución más robusta es establecer la configuración regional al comienzo del script para asegurarse de que funcionará independientemente de la configuración regional del usuario:
fuente
.
(por lo tanto, no en la mitad del mundo donde está el separador decimal,
).zsh
No tiene ese problema.LC_ALL
, eso también significa que los números no se mostrarán (o ingresarán) en el formato preferido del usuario. Ver unix.stackexchange.com/questions/87745/what-does-lc-all-c-do/… para un enfoque potencialmente mejor..
todos modos.Que utiliza la
dc
calculadora paras
rasgaron el valor$min
en el registroa
yd
uplicates el valor de$val
en la parte superior de su pila de ejecución principal. Luegol
coloca el contenidoa
en la parte superior de la pila, en cuyo punto se ve así:La
<
hace estallar la parte superior dos entradas fuera de la pila y los compara. Entonces la pila se ve así:Si la entrada superior era menor que la segunda hacia arriba, empuja el contenido
a
hacia arriba, por lo que la pila se ve así:De lo contrario, no hace nada y la pila todavía se ve así:
Luego simplemente
p
borra la entrada de la pila superior.Entonces para tu problema:
Pero:
fuente
¿Por qué no usar viejo, bueno
expr
?Ejemplo de sintaxis:
Para expresiones verdaderas , el código de salida expr es 0, con la cadena '1' enviada a stdout. Invertir para expresiones falsas .
He comprobado esto con GNU y FreeBSD 8 expr.
fuente
expr 1.09 '<' -1.1
imprimirá1
y saldrá con0
(éxito).Para verificar si dos números (posiblemente fraccionarios) están en orden,
sort
es (razonablemente) portátil:Sin embargo, si realmente desea mantener actualizado un valor mínimo, entonces no necesita un
if
. Ordena los números y usa siempre el primero (mínimo):fuente
Por lo general, hago cosas similares con el código de Python incrustado:
fuente
fuente