Estoy tratando de dividir dos anchos de imagen en un script Bash, pero bash me da 0
como resultado:
RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))
Estudié la guía Bash y sé que debería usar bc
, en todos los ejemplos que usan en Internet bc
. En echo
Traté de poner la misma cosa en mi SCALE
, pero no 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 0.5
?
bash
floating-point
arithmetic-expressions
Medya Gh
fuente
fuente
Respuestas:
No puedes bash solo hace enteros; se debe delegar a una herramienta como
bc
.fuente
VAR=$(echo "scale=2; $IMG_WIDTH/$IMG2_WIDTH" | bc)
oVAR=$(bc <<<"scale=2;$IMG_WIDTH/$IMG2_WIDTH")
sin $ (()) (paréntesis dobles); que es expandido por el bash antes de ejecutar el comandoPuedes hacerlo:
ACTUALIZACIÓN
20130926
: puede usar:fuente
bc -l <<< 'scale=2; 100/3'
Unless specifically mentioned the scale of the result is the maximum scale of the expressions involved.
Y hay una nota adicional para el/
operador:The scale of the result is the value of the variable scale.
bc <<< 'scale=1; 1*3.00001'
escala es realmente 5 por alguna razón, labc <<< 'scale=1; 1/3.000001'
escala es 1. Curiosamente, dividir por 1 lo pone en orden: labc <<< 'scale=1; 1*3.00001/1'
escala es 1intento
Como han señalado otros,
bash
no admite la aritmética de coma flotante, aunque podría simularla con algún truco decimal fijo, por ejemplo, con dos decimales:Salida:
Vea la respuesta de Nilfred para un enfoque similar pero más conciso.
Alternativas
Además de lo mencionado
bc
y lasawk
alternativas, también están las siguientes:clisp
con salida limpiada:
o a través de stdin:
corriente continua
calculadora cli genio
ghostscript
gnuplot
jq
O:
ksh
lua
o a través de stdin:
maxima
con salida limpiada:
nodo
octava
perl
python2
python3
R
con salida limpiada:
rubí
wcalc
Con salida limpiada:
zsh
unidades
Con salida compacta:
Otras fuentes
Stéphane Chazelas respondió una pregunta similar en Unix.SX.
fuente
echo 1/3 | node -p
es corto.Mejorando un poco la respuesta de marvin:
bc no siempre viene como paquete instalado.
fuente
exit
para evitar que lea desde su flujo de entrada. También sugiero usar las-v
banderas de awk para prevenir el síndrome del palillo inclinado. Entonces:RESULT=$(awk -v dividend="${IMG_WIDTH}" -v divisor="${IMG2_WIDTH}" 'BEGIN {printf "%.2f", dividend/divisor; exit(0)}')
RESULT=$(awk '{printf("result= %.2f\n",$1/$2)}' <<<" $IMG_WIDTH $IMG2_WIDTH "
.bc
es parte de POSIX, generalmente está preinstalado.Puede usar bc por la
-l
opción (la letra L)fuente
-l
en mi sistema, bc no hace matemática de punto flotante.Como alternativa a bc, puede usar awk dentro de su script.
Por ejemplo:
En lo anterior, "% .2f" le dice a la función printf que devuelva un número de coma flotante con dos dígitos después del decimal. Usé echo para canalizar las variables como campos ya que awk funciona correctamente en ellas. "$ 1" y "$ 2" se refieren a la entrada del primer y segundo campo en awk.
Y puede almacenar el resultado como alguna otra variable usando:
fuente
Es el momento perfecto para probar zsh, un superconjunto (casi) bash, con muchas características adicionales que incluyen matemáticas de coma flotante. Así es como sería su ejemplo en zsh:
Esta publicación puede ayudarte: bash - ¿Vale la pena cambiar a zsh para uso casual?
fuente
Bueno, antes de flotar era un momento en el que se usaba la lógica de decimales fijos:
La última línea es un bashim, si no usa bash, intente este código en su lugar:
La razón detrás del código es: multiplique por 100 antes de dividir para obtener 2 decimales.
fuente
Si encontró la variante de su preferencia, también puede incluirla en una función.
Aquí estoy envolviendo algo de bashismo en una función div:
Un trazador de líneas:
O multilínea:
Ahora tienes la función
y úsalo como
ACTUALIZACIÓN Agregué un pequeño script que le proporciona las operaciones básicas con números de punto flotante para bash:
Uso:
Y aquí el guión:
fuente
local _d=${3:-2}
es más simpleNo es realmente punto flotante, pero si quieres algo que establezca más de un resultado en una invocación de bc ...
calcula el área y el diámetro de un círculo cuyo radio se da en $ 1
fuente
Hay escenarios en los que no puede usar bc porque simplemente podría no estar presente, como en algunas versiones reducidas de busybox o sistemas integrados. En cualquier caso, limitar las dependencias externas siempre es algo bueno, por lo que siempre puede agregar ceros al número que se divide por (numerador), es decir, multiplicar por una potencia de 10 (debe elegir una potencia de 10 de acuerdo con la precisión que necesita), eso hará que la división genere un número entero. Una vez que tenga ese entero, trátelo como una cadena y coloque el punto decimal (moviéndolo de derecha a izquierda) varias veces igual a la potencia de diez por el que multiplicó el numerador. Esta es una manera simple de obtener resultados flotantes utilizando solo números enteros.
fuente
Si bien no puede usar la división de punto flotante en Bash, puede usar la división de punto fijo. Todo lo que necesita hacer es multiplicar sus enteros por una potencia de 10 y luego dividir la parte entera y usar una operación de módulo para obtener la parte fraccional. Redondeo según sea necesario.
fuente
Sé que es viejo, pero demasiado tentador. entonces, la respuesta es: no puedes ... pero sí puedes. intentemos esto:
así obtienes 2 dígitos después del punto, truncado (llámalo redondeando a la parte inferior, jaja) en bash puro (no es necesario iniciar otros procesos). por supuesto, si solo necesita un dígito después del punto, multiplique por 10 y realice el módulo 10.
qué hace esto:
bonus track : la versión bc x 1000 tardó 1,8 segundos en mi computadora portátil, mientras que la versión pura bash tardó 0,016 segundos.
fuente
Cómo hacer cálculos de coma flotante en bash:
En lugar de usar " here strings " (
<<<
) con elbc
comando, como lo hace uno de los ejemplos más votados , aquí está mibc
ejemplo de coma flotante favorito , directamente desde laEXAMPLES
sección de lasbc
páginas man (veaman bc
las páginas del manual).Antes de empezar, saber que una ecuación para pi es:
pi = 4*atan(1)
.a()
a continuación se muestra labc
función matemática paraatan()
.Así se almacena el resultado de un cálculo de coma flotante en una variable bash, en este caso en una variable llamada
pi
. Tenga en cuenta quescale=10
establece el número de dígitos decimales de precisión en 10 en este caso. Los dígitos decimales después de este lugar se truncan .Ahora, para tener una sola línea de código que también imprima el valor de esta variable, simplemente agregue el
echo
comando al final como un comando de seguimiento, de la siguiente manera. Tenga en cuenta el truncamiento en 10 decimales, según lo ordenado:Finalmente, echemos un poco de redondeo. Aquí usaremos la
printf
función para redondear a 4 decimales. Tenga en cuenta que las3.14159...
rondas ahora a3.1416
. Como estamos redondeando, ya no necesitamos usarscale=10
para truncar a 10 decimales, por lo que simplemente eliminaremos esa parte. Aquí está la solución final:Aquí hay otra gran aplicación y demostración de las técnicas anteriores: medir e imprimir el tiempo de ejecución.
Tenga en cuenta que
dt_min
se redondea de0.01666666666...
a0.017
:Relacionado:
fuente
Usa calc. Es el ejemplo más fácil que encontré:
fuente
Para aquellos que intentan calcular porcentajes con la respuesta aceptada, pero están perdiendo precisión:
Si ejecuta esto:
Solo obtienes
99.00
, lo que está perdiendo precisión.Si lo ejecutas de esta manera:
Ahora lo tienes
99.99
.Porque está escalando solo en el momento de la impresión.
Consulte aquí
fuente
** Matemáticas de punto flotante a prueba de inyecciones en bash / shell **
Nota: El enfoque de esta respuesta es proporcionar ideas para una solución segura para la inyección para realizar las matemáticas en bash (u otros shells). Por supuesto, se puede usar lo mismo, con pequeños ajustes para realizar un procesamiento avanzado de cadenas, etc.
La mayoría de las soluciones que se presentaron, construyen pequeños scriptlet sobre la marcha, utilizando datos externos (variables, archivos, línea de comando, variables de entorno). La entrada externa se puede usar para inyectar código malicioso en el motor, muchos de ellos
A continuación se muestra una comparación sobre el uso de varios idiomas para realizar cálculos matemáticos básicos, donde el resultado es punto flotante. Calcula A + B * 0.1 (como punto flotante).
Todos los intentos de solución evitan crear scriptlets dinámicos, que son extremadamente difíciles de mantener. En su lugar, usan un programa estático y pasan los parámetros a la variable designada. Manejarán con seguridad los parámetros con caracteres especiales, reduciendo la posibilidad de inyección de código. La excepción es 'BC' que no proporciona facilidad de entrada / salida
La excepción es 'bc', que no proporciona ninguna entrada / salida, todos los datos provienen de programas en stdin y toda la salida va a stdout. Todos los cálculos se ejecutan en un entorno limitado, que no permite efectos secundarios (abrir archivos, etc.). En teoría, la inyección es segura por diseño.
fuente
python3 -c 'import sys ; *a, = map(float, sys.argv[1:]) ; print(a[0] + a[1]*0.1 + a[2])' "$A" "$B"
"4200.0" ==> 4205.63aquí está el comando awk: -F = separador de campo == +
fuente