2010-04-21 22 views
5

en bash que necesito para comparar dos números flotantes, uno que defino en el guión y la otra lectura como parametro, por lo que hago:flotador condicional en bash

if [[ $aff -gt 0 ]] 
    then 
      a=b 
      echo "xxx "$aff 
      #echo $CX $CY $CZ $aff 
    fi 

pero me sale el error:

[[: -309,585300: error de sintaxis: inválido operador aritmético (distintivo de error es" 0.585300")

¿Qué le pasa?

Gracias

+0

Supongo que ya está familiarizado con [Lo que todo científico informático debe saber sobre la aritmética de coma flotante] (http://docs.sun.com/source/806-3568/ncg_goldberg.html) . –

+2

es como si te dijera que para entender el comportamiento humano solo necesitas estar familiarizado con la ecuación de Schroedinger – flow

+2

@Dennis: esta pregunta no requiere ninguno de los conocimientos en ese documento; no * todo * sobre flotadores es difícil, y las comparaciones más grandes/más pequeñas simplemente funcionan como se esperaba. –

Respuesta

4

uso awk

#!/bin/bash 
num1=0.3 
num2=0.2 
if [ -n "$num1" -a -n "$num2" ];then 
    result=$(awk -vn1="$num1" -vn2="$num2" 'BEGIN{print (n1>n2)?1:0 }') 
    echo $result 
    if [ "$result" -eq 1 ];then 
    echo "$num1 greater than $num2" 
    fi 
fi 
+0

muy agradable de hecho. un último comentario, num1 se lee de algún archivo y en algunos casos está vacío, por lo que la comparación da resultados extraños. ¿Cómo puede volver a comprobar de alguna manera "si num1 está vacío, entonces num1 = 0"? – flow

+0

use '-n' para probar cadenas no vacías. ver 'man test' para más información – ghostdog74

3

Tanto test (que normalmente está vinculado a como [) y la bash -builtin números enteros solamente de apoyo equivalentes.

0

me gustaría utilizar awk para ello:

e=2.718281828459045 
pi=3.141592653589793 
if [ "yes" = "$(echo | awk "($e <= $pi) { print \"yes\"; }")" ]; then 
    echo "lessthanorequal" 
else 
    echo "larger" 
fi 
6

Usando aC en lugar de awk:

float1='0.43255' 
float2='0.801222' 

if [[ $(echo "if (${float1} > ${float2}) 1 else 0" | bc) -eq 1 ]]; then 
    echo "${float1} > ${float2}" 
else 
    echo "${float1} <= ${float2}" 
fi 
1

Uso bc para comprobar los cálculos

a="1.21231" 
b="2.22454" 
c=$(echo "$a < $b" | bc) 
if [ $c = '1' ]; then 
    echo 'a is smaller than b' 
else 
    echo 'a is larger than b' 
fi 
0

La solución más sencilla es la siguiente:

f1=0.45 
f2=0.33 
if [[ $f1 > $f2 ]] ; then echo "f1 is greater then f2"; fi 

cuales (en OSX) Salidas:

f1 is greater then f2 

He aquí otro ejemplo la combinación de punto flotante y la aritmética de enteros (que necesita la gran calc.pl guión Perl que poco se puede descargar desde here):

dateDiff=1.9864 
nObs=3 
i=1 
while [[ $dateDiff > 0 ]] && [ $i -le $nObs ] 
do 
    echo "$dateDiff > 0" 
    dateDiff=`calc.pl $dateDiff-0.224` 
    i=$((i+1)) 
done 

que emite

1.9864 > 0 
1.7624 > 0 
1.5384 > 0 
+0

Me acabo de dar cuenta de que ** esto realmente no funciona porque bash ignora el punto decimal ** silenciosamente. Solo funciona al comparar flotadores para circunstancias especiales, como cuando tienen el mismo número de dígitos ANTES del punto decimal. La solución es usar solo la parte entera de los flotantes que está comparando (usando -gt en lugar de> y -lt en lugar de <; eso es lo suficientemente bueno para mis aplicaciones), o dividir el entero y las partes decimales y compararlas _como integers_ por separado. –