2012-08-27 19 views
32

me gustaría hacer la siguiente operación en mi guión:División de guión y de punto flotante

1 - ((m - 20)/34) 

quisiera asignar el resultado de esta operación a otra variable. Quiero que mi script use matemáticas de coma flotante. Por ejemplo, para m = 34:

results = 1 - ((34 - 20)/34) == 0.588 

Respuesta

24

Bash no hace matemática en coma flotante. Puede usar awk o bc para manejar esto. Este es un ejemplo awk:

$ m=34; awk -v m=$m 'BEGIN { print 1 - ((m - 20)/34) }' 
0.588235 

Para asignar la salida a una variable:

var=$(awk -v m=$m 'BEGIN { print 1 - ((m - 20)/34) }') 
47

Se puede usar la calculadora bc. Lo hará matemáticas de precisión arbitraria usando decimales (no binario de punto flotante) si se establece increease scale de su valor predeterminado de 0:

$ m=34 
$ bc <<< "scale = 10; 1 - (($m - 20)/34)" 
.5882352942 

La opción -l se carga la biblioteca matemática estándar y por defecto la escala a 20:

$ bc -l <<< "1 - (($m - 20)/34)" 
.58823529411764705883 

luego, puede usar printf para dar formato a la salida, si así lo desea:

printf "%.3f\n" "$(bc -l ...)" 
+0

@ rubo77 hice algo como esto 'let fail_percent = 0 dejó totales = $ ((+ pass_count fail_count)) printf "fallar porcentaje es% f \ n" $ (BC - l <<< "($ fail_count/$ total)") ' aquí el total = 16 y fail_count = 15, obtengo la respuesta como .93750000000000000000, pero viene con un error como printf número no válido He dado #!/bin/bash en el comienzo del script ... ¿CUALQUIER idea de por qué el error? –

+0

usando 'printf '% f \ n' $ (bc -l <<< 1.2)' Recibo el error 'bash: printf: 1.2: Ungültige Zahl. ' – rubo77

17

Teach fiesta por ejemplo, división entera con los resultados de punto flotante:

#!/bin/bash 

div() # Arguments: dividend and divisor 
{ 
     if [ $2 -eq 0 ]; then echo division by 0; exit; fi 
     local p=12       # precision 
     local c=${c:-0}      # precision counter 
     local d=.        # decimal separator 
     local r=$(($1/$2)); echo -n $r  # result of division 
     local m=$(($r*$2)) 
     [ $c -eq 0 ] && [ $m -ne $1 ] && echo -n $d 
     [ $1 -eq $m ] || [ $c -eq $p ] && return 
     local e=$(($1-$m)) 
     let c=c+1 
     div $(($e*10)) $2 
} 

    result=$(div 1080 633)     # write to variable 
    echo $result 

    result=$(div 7 34) 
    echo $result 

    result=$(div 8 32) 
    echo $result 

    result=$(div 246891510 2) 
    echo $result 

    result=$(div 5000000 177) 
    echo $result 

Salida:

1.706161137440 
    0.205882352941 
    0.25 
    123445755 
    28248.587570621468 
+0

Muy bonito. Esto incluso sería POSIX-obediente si el 'let c = c + 1' se cambiara a' c = $ (($ c + 1)) ', pero esa recursión parece costosa ... –

-2

Usar este comando de abrir este archivo con el editor favorito como:

$ sudo vim /usr/bin/div 

Luego pega este código:

#!/bin/bash 
# Author: Danial Rikhteh Garan ([email protected]) 

if [[ -z "$1" ]] || [[ -z "$2" ]]; then 
    echo "Please input two number" 
    echo "for 100/50 use: div 10 50" 
    exit 1; 
fi 

div=$(echo "$1/$2" | bc -l); 
echo 0$div | sed 's/[0]*$//g' 

Ahora chmod a 755:

$ sudo chmod 755 /usr/bin/div 

ahora lo utilizan:

$ div 5 100 
0.05 

En la secuencia de comandos se puede utilizar este:

var=$(div 5 100); 
echo "$var" 
3
echo $a/$b|bc -l 

da el resultado.

Ejemplo:

read a b 
echo $a/$b|bc -l 

Introduzca un valor b & como 10 3, se obtiene 3.3333333333

Si desea almacenar el valor de otra variable a continuación, utilizar el código

read a b 
c=`echo $a/$b|bc -l` 
echo $c 

También da el mismo resultado que el anterior. Inténtelo ...

Cuestiones relacionadas