Quiero hacer un bucle for en bash con 0.02 como incrementos intenté
for ((i=4.00;i<5.42;i+=0.02))
do
commands
done
Pero no funcionó.
bash
for
floating-point
Mehrshad
fuente
fuente
bc
, pero detenerse en 4.52 puede ser complicado. use la sugerencia de @roaima, tenga una var auxiliar con el paso 2 y usei=$(echo $tmp_var / 100 | bc)
Respuestas:
La lectura de la
bash
página del manual proporciona la siguiente información:y luego obtenemos esta sección
Por lo tanto, se puede ver claramente que no puede usar un
for
bucle con valores no enteros.Una solución puede ser simplemente multiplicar todos sus componentes de bucle por 100, permitiendo esto donde más tarde los use, así:
fuente
k=400;k<542;k+=2
que evita posibles problemas aritméticos de coma flotante.bc
), bifurca un proceso, crea un archivo temporal (para la cadena here), ejecutabc
en él (lo que implica cargar un archivo ejecutable y bibliotecas compartidas y inicializándolos), espere y limpie. Correrbc
una vez para hacer el ciclo sería mucho más eficiente.i=$(bc <<< "scale...")
oi=$(echo "scale..." | bc)
<<<
viene)bash
yksh
. Tenga en cuenta que cambiar a otro shell quebash
le dará un mejor impulso de rendimiento que usar la otra sintaxis de todos modos.<<<
(zsh, mksh, ksh93, Yash) también apoyan la aritmética de punto flotante (zsh
,ksh93
,yash
)).Evite bucles en conchas.
Si quieres hacer aritmética, usa
awk
obc
:O
Tenga en cuenta que
awk
(al contrario debc
) funciona con ladouble
representación de números de coma flotante de sus procesadores (probablemente tipo IEEE 754 ). Como resultado, dado que esos números son aproximaciones binarias de esos números decimales, puede tener algunas sorpresas:Si agrega un
OFMT="%.17g"
puede ver el motivo de la falta0.3
:bc
tiene una precisión arbitraria, por lo que no tiene este tipo de problema.Tenga en cuenta que, de manera predeterminada (a menos que modifique el formato de salida
OFMT
o useprintf
especificaciones de formato explícito), seawk
usa%.6g
para mostrar números de coma flotante, por lo que cambiaría a 1e6 y superior para números de coma flotante superiores a 1,000,000 y truncaría la parte fraccionaria para números altos (100000.02 se mostrará como 100000).Si realmente necesita usar un bucle cáscara, porque, por ejemplo, desea ejecutar comandos específicos para cada iteración de este bucle, o bien utilizar un depósito de flotación apoyo aritmética de punto como
zsh
,yash
oksh93
o generar la lista de valores con un comando que el anterior (oseq
si está disponible) y repita su salida.Me gusta:
O:
a menos que supere los límites de los números de coma flotante de su procesador,
seq
maneja los errores incurridos por aproximaciones de coma flotante con más gracia que laawk
versión anterior.Si no tiene
seq
(un comando GNU), puede hacer uno más confiable como una función como:Eso funcionaría mejor para cosas como
seq 100000000001 0.000000001 100000000001.000000005
. Sin embargo, tenga en cuenta que tener números con una precisión arbitrariamente alta no ayudará mucho si vamos a pasarlos a comandos que no los admiten.fuente
unset IFS
en el primer ejemplo?IFS=$'\n'
pero eso no funciona en todos los shells. OIFS='<a-litteral-newline-here>'
eso no es muy legible. O podemos dividirnos en palabras (espacio, tabulación, nueva línea) como se obtiene con el valor predeterminado de $ IFS o si desarma IFS y también funciona aquí.IFS
, porque sabemos queseq
la salida no tiene espacios en los que debemos evitar dividirnos. Principalmente está ahí para asegurarse de que se dé cuenta de que este ejemplo dependeIFS
, lo que podría ser importante para un comando de generación de lista diferente.Use "seq" - imprima una secuencia de números
seq PRIMER INCREMENTO ÚLTIMO
fuente
Como otros han sugerido, puede usar bc:
fuente