¿Cómo uso la aritmética de punto flotante en bash?

Resuelto Medya Gh asked hace 12 años • 24 respuestas

Estoy intentando dividir dos anchos de imagen en un script Bash, pero bash me da 0el resultado:

RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))

Estudié la guía de Bash y sé que debería usarla bcen todos los ejemplos que usan en Internet bc. echoIntenté poner lo mismo en mi pero SCALEno funcionó.

Aquí está el ejemplo que encontré en los tutoriales:

echo "scale=2; ${userinput}" | bc 

¿Cómo puedo hacer que Bash me dé un flotador como 0.5?

Medya Gh avatar Oct 04 '12 14:10 Medya Gh
Aceptado

No puedes. bash sólo procesa números enteros; debes delegar a una herramienta como bc.

Ignacio Vazquez-Abrams avatar Oct 04 '2012 07:10 Ignacio Vazquez-Abrams

Puedes hacerlo:

bc <<< 'scale=2; 100/3'
33.33

ACTUALIZACIÓN 20130926 : puedes usar:

bc -l <<< '100/3' # saves a few hits
33.33333333333333333333
aayoubi avatar Oct 04 '2012 08:10 aayoubi

intento

Como han señalado otros, bashno admite aritmética de coma flotante, aunque se puede simular con algún truco de decimales fijos, por ejemplo, con dos decimales:

echo $(( 100 * 1 / 3 )) | sed -e 's/..$/.&/;t' -e 's/.$/.0&/'

Producción:

.33

Consulte la respuesta de Nilfred para obtener un enfoque similar pero más conciso.

Alternativas

Además de las alternativas mencionadas bcy awktambién existen las siguientes:

recortar

clisp -x '(/ 1.0 3)'

con salida limpia:

clisp --quiet -x '(/ 1.0 3)'

o a través de stdin:

echo '(/ 1.0 3)' | clisp --quiet | tail -n1

corriente continua

echo 2k 1 3 /p | dc

calculadora genio cli

echo 1/3.0 | genius

guión fantasma

echo 1 3 div = | gs -dNODISPLAY -dQUIET | sed -n '1s/.*>//p' 

parcela gnuplot

echo 'pr 1/3.' | gnuplot

Imagenmagia

convert xc: -format '%[fx:1/3]' info:

o a través de stdin:

echo 1/3 | { convert xc: -format "%[fx:$(cat)]" info:; }

jq

jq -n 1/3

o a través de stdin:

echo 1/3 | jq -nf /dev/stdin

ksh

echo 'print $(( 1/3. ))' | ksh

lua

lua -e 'print(1/3)'

o mediante stdin:

echo 'print(1/3)' | lua

máximos

echo '1/3,numer;' | maxima

con salida limpia:

echo '1/3,numer;' | maxima --quiet | sed -En '2s/[^ ]+ [^ ]+ +//p'

nodo

echo 1/3 | node -p

octava

echo 1/3 | octave

perla

echo print 1/3 | perl

PHP

php -r 'echo 1/3;'

o a través de stdin:

echo '<?php print 1/3;?>' | php

pitón2

echo print 1/3. | python2

python3

echo 'print(1/3)' | python3

R

echo 1/3 | R --no-save

con salida limpia:

echo 1/3 | R --vanilla --quiet | sed -n '2s/.* //p'

rubí

echo puts 1/3.0 | ruby

unidades

units 1/3

con salida compacta:

units --com 1/3

wcalc

echo 1/3 | wcalc

con salida limpia:

echo 1/3 | wcalc | tr -d ' ' | cut -d= -f2

zsh

print $(( 1/3. ))

o a través de stdin:

echo 'print $(( 1/3. ))' | zsh

Otras fuentes

Stéphane Chazelas respondió a una pregunta similar en UL.

Thor avatar Feb 16 '2015 12:02 Thor

Mejorando un poco la respuesta de marvin:

RESULT=$(awk "BEGIN {printf \"%.2f\",${IMG_WIDTH}/${IMG2_WIDTH}}")

bc no siempre viene como paquete instalado.

adrianlzt avatar Mar 14 '2014 13:03 adrianlzt

Podrías usar bc por la -lopción (la letra L)

RESULT=$(echo "$IMG_WIDTH/$IMG2_WIDTH" | bc -l)
user1314742 avatar Mar 27 '2013 16:03 user1314742