¿Es esta la forma correcta de hacer conversión de flotante a entero en bash? ¿Hay algún otro método?
flotToint() {
printf "%.0f\n" "$@"
}
bash
floating-point
Rahul Patil
fuente
fuente
%.0f
se redondeará hacia arriba o hacia abajo. ¿Es eso lo que quieres? Puedes usarprintf "%d\n" "$@" 2>/dev/null
para cortar la fracción.Respuestas:
golpetazo
En
bash
, eso es probablemente tan bueno como se pone. Eso usa un caparazón incorporado. Si necesita el resultado en una variable, puede usar la sustitución de comandos o labash
específica (aunque ahora también es compatible conzsh
):Podrías hacerlo:
Pero eso eliminaría la parte fraccionaria en lugar de darle el número entero más cercano y eso no funcionaría para valores
$float
similares1.2e9
o,.12
por ejemplo.También tenga en cuenta las posibles limitaciones debido a la representación interna de flotadores:
Sí obtienes un número entero, pero es probable que no puedas usar ese número entero en ninguna parte.
Además, como señaló @BinaryZebra, en varias
printf
implementaciones (bash, ksh93, yash, no GNU, zsh, dash), se ve afectado por la configuración regional (el separador decimal que puede ser.
o,
).Por lo tanto, si sus flotantes siempre se expresan con el punto como separador decimal y desea que se trate como tal,
printf
independientemente de la configuración regional del usuario que invoca su secuencia de comandos, deberá corregir la configuración regional en C:Con
yash
, también puedes hacer:(vea abajo).
POSIX
no es POSIX ya
%f
que no es necesario que sea compatible con POSIX.POSIXY, puedes hacer:
Ese no se ve afectado por la configuración regional (la coma no puede ser un separador decimal
awk
ya que ya es un carácter especial en la sintaxis allí (print 1,2
igual queprint 1, 2
para pasar dos argumentosprint
)zsh
En
zsh
(que admite aritmética de coma flotante (el separador decimal es siempre el punto)), tiene larint()
función matemática para darle el entero más cercano como flotante (como enC
) yint()
para darle un entero desde un flotante (como enawk
). Entonces puedes hacer:O:
Sin embargo, tenga en cuenta que si bien
double
s puede representar números muy grandes, los enteros son mucho más limitados.ksh93
ksh93 fue el primer shell similar a Bourne que admitió la aritmética de coma flotante. ksh93 optimiza la sustitución de comandos al no usar una tubería o bifurcación cuando los comandos son solo comandos incorporados. Entonces
no se bifurca O mejor:
que tampoco se bifurca pero tampoco se toma la molestia de crear un entorno falso de subshell.
También puedes hacer:
Pero cuidado con:
También puedes hacer:
Pero como por
zsh
:Tenga en cuenta que la
ksh93
aritmética de coma flotante respeta la configuración del separador decimal en la configuración regional (aunque de,
lo contrario es un operador matemático ($((1,2))
sería 6/5 en una configuración regional en francés / alemán ... y lo mismo que$((1, 2))
, eso es 2 en una configuración regional en inglés) .yash
yash también admite aritmética de coma flotante, pero no tiene funciones matemáticas como
ksh93
/zsh
'srint()
. Sin embargo, puede convertir un número a entero utilizando el binario o el operador (también funcionazsh
pero no enksh93
). Sin embargo, tenga en cuenta que trunca la parte decimal, no le da el entero más cercano:yash
respeta el separador decimal de la configuración regional en la salida, pero no para las constantes literales de coma flotante en sus expresiones aritméticas, lo que puede causar sorpresas:Es bueno de alguna manera, ya que puede usar constantes de punto flotante en sus scripts que usan el punto y no tiene que preocuparse de que deje de funcionar en otras configuraciones regionales, pero aún así pueda manejar los números expresados por el usuario durante tanto tiempo. como recuerdas hacer:
fuente
int=${float%.*}
funcionó muy bien en mi script bash (versión 3.2.57 (1) -release) en una Mac (versión 10.13.4 (17E199)).,
la raíz decimal. Ver la sección sobreLC_ALL=C
bc
- Un lenguaje de calculadora de precisión arbitrariaint (float) debería verse así:
Para redondear mejor use esto:
Ejemplo:
fuente
float=-2; echo "($float+0.5)/1" | bc
da-1
.La respuesta anterior presentada fue casi correcta: "Podría hacer:
Pero eso eliminaría la parte fraccionaria en lugar de darle el número entero más cercano y eso no funcionaría para valores de $ float como 1.2e9 o .12, por ejemplo ... "
Solo úsalo
${float%%.*}
.fuente
Un hacky muy simple es
Salida de muestra
fuente
sed
, pero lacut
solución es más simple. Prefierosed
ocut
ya que están en mi humilde opinión más disponibles en objetivos incrustados queawk
(que todavía es bastante común a través debusybox
quebc
).Relacionado:
Complementando la respuesta de @ Stéphane Chazelas
awk
:fuente
printf
, o si hay alguna otra razón para preferir awk sobre el incorporadoprintf
.