Cómo realizar cálculos de punto flotante en scripts Bash de Linux

Puntos clave

  • El shell Linux Bash solo admite aritmética de enteros y no puede realizar cálculos con números de punto flotante.
  • La utilidad bc en Linux permite realizar cálculos precisos de punto flotante de forma interactiva y en scripts de shell.
  • Con bc, puede establecer el número de decimales para mostrar y realizar cálculos con precisión arbitraria, incluido el uso de funciones de biblioteca matemática estándar.

El shell de Linux Bash solo admite aritmética de enteros. No puede comprender ni manejar cálculos de punto flotante. La utilidad bc proporciona cálculos precisos de punto flotante de forma interactiva y en scripts de shell.

→ Índice de contenidos
  • Porque Bash solo admite números enteros
  • Usando bc interactivamente
  • La biblioteca de matemáticas estándar
  • Enviar entrada a bc en la línea de comando
  • Usando bc en scripts de shell Bash
  • todo suma
  • Porque Bash solo admite números enteros

    La decisión de diseño original de limitar el shell Bourne de Unix a la aritmética de enteros puede haber tenido su origen en la asignación inicial de un número entero en un solo byte de RAM. Quizás nunca sepamos qué hubo realmente detrás de esa decisión. Tampoco, de hecho, por qué la versión Linux del shell Bourne, el shell Bash, decidió hacer lo mismo.

    Por sí solo, Bash no puede realizar cálculos con números de punto flotante, y los cálculos con números enteros que tendrían una parte fraccionaria en la respuesta se informan como valores enteros truncados. Esto es cierto en la línea de comando y en los scripts de shell Bash. Dependiendo del caso de uso, esto puede resultar problemático o perturbador.

    Linux viene con dos aplicaciones de utilidad que le permiten realizar cálculos de punto flotante. Uno de ellos es DC. Es un poco divertido porque funciona en notación polaca inversa. La otra herramienta es bc. Se puede utilizar de forma interactiva o como comando y es la solución de la que hablaremos aquí.

    Relacionado: 9 ejemplos de secuencias de comandos Bash

    El problema

    Dejemos que Bash divida seis por tres.

     echo $((6 / 3)) 

    Obtenemos nuestra respuesta esperada de dos. Ahora dividamos seis por siete. Claramente, esto tendrá una respuesta fraccionaria.

     echo $((6 / 7)) 

    Dividir dos números enteros en la línea de comando Bash con un resto fraccionario.  El resto nunca se muestra.

    Obviamente Zero está equivocado. Intentemos de nuevo, dividiendo 16 entre 7.

     echo $((16 / 7)) 

    Ilustrando el problema con BAsh que solo admite aritmética de enteros dividiendo dos números enteros.  El resto fraccionario se descarta.

    Obtenemos una respuesta de dos. Lo que sucede es que se descarta la parte fraccionaria de la respuesta, por lo que se trunca la respuesta. En el primer ejemplo no había parte fraccionaria, por lo que obtenemos la respuesta correcta.

    El segundo ejemplo no tenía elementos enteros en la respuesta, solo una parte fraccionaria. Como se ha descartado la parte fraccionaria, la respuesta que se nos muestra es cero.

    En el tercer ejemplo, 7 se divide dos veces entre 16, con un resto fraccionario. Nuevamente se descarta el resto y se trunca el resultado.

    Usando bc interactivamente

    Puede utilizar bc como calculadora interactiva escribiendo bc y presionando la tecla "Enter".

     bc 

    El mensaje de bienvenida y el mensaje bc.

    La aplicación bc se inicia, anuncia el número de versión y luego espera su entrada. Al escribir un cálculo y presionar "Entrar", se evaluará el cálculo y se mostrará la respuesta.

     16 * 4

    1024 / 32

    2^2 * 1024

    Tres ejemplos de cálculos en bc, en modo interactivo

    Puede utilizar "Ctrl+L" para borrar la pantalla y "Ctrl+D" para salir del programa. Probemos un cálculo que tendrá un componente fraccionario en la respuesta.

     22 / 7 

    bc por defecto no muestra decimales.  Pi se trunca a 3.

    No es lo que esperábamos. Contrariamente a la intuición, aunque bc nos permite usar precisión arbitraria, de forma predeterminada no mostrará el punto decimal ni los dígitos que le siguen.

    Para hacer visible la respuesta verdadera, necesitamos decirle a bc cuántos decimales mostrar. Esto lo hacemos con el comando “escalas”. Le pediremos siete decimales y reharemos el cálculo.

     scale=7
    22 / 7

    Utilice la escala para indicarle a bc que muestre hasta 7 decimales en los resultados del cálculo.

    Finalmente estamos llegando a alguna parte. La configuración de "escala" permanece vigente hasta que la cambie. Configurar el número de decimales le indica a bc el número máximo de dígitos que se mostrarán. Si una respuesta no requiere tantos decimales, se muestra con el número requerido de decimales y nada más. No está lleno de ceros sin sentido.

     scale=10
    0.300003 * 0.5

    bc muestra sólo los decimales necesarios.  Configurar la escala en 10 no forzará el uso de 10 decimales.  Si una respuesta requiere menos decimales, estos serán los únicos que se mostrarán.

    Puede enumerar diferentes cálculos en la misma línea usando un punto y coma ";" para separarlos. Las respuestas se muestran por fila como de costumbre, en el orden en que se enumeraron los cálculos.

     25 * 6; 12.5 + 45.001; 3 + 5 + 7 + 9 

    Puede agregar varios cálculos a una línea separándolos con punto y coma.

    También puede incluir el comando "escala" en la lista.

     scale=8; 22 / 7; scale=3; 0.3 * 0.071 

    Puede cambiar la configuración de escala para cada cálculo, incluso para cálculos en la misma línea de comando

    La biblioteca de matemáticas estándar

    La opción -l (biblioteca matemática estándar) hace que bc cargue un conjunto de funciones y establezca la "escala" en 20 decimales.

     bc -l
    22 / 7

    bc se lanzó con la opción -l, mostrando pi calculado con 20 decimales

    Con la biblioteca estándar cargada, puede utilizar estas funciones en sus cálculos.

    • s(x): El pecho de x
    • c(x): El coseno de x.
    • hacha): El arcotangente de x
    • l(x): El logaritmo natural de x
    • y (x): El exponencial de e en el valor de x
    • j(n,x): La función de Bessel de orden entero n de x.

    El seno, el coseno y el arcotangente utilizan valores en radianes.

     s (1.1)
     
    c (.891207)
     
    a (.628473)

    Cálculo de seno, coseno y arcotan en bc en modo interactivo

    Enviar entrada a bc en la línea de comando

    Puede utilizar redirección y canalizaciones para enviar entradas a bc. Procese la entrada y muestre la respuesta en la ventana del terminal.

    Puede redirigir a bc con o sin la opción -l (biblioteca matemática estándar).

     bc <<< 22/7
    bc -l <<< 22/7

    Redirigir la entrada a bc y bc -l

    Para redirigir la entrada a bc, la entrada debe ser la salida de otro proceso. Es conveniente utilizar eco para esto.

     echo 22/7 | bc
    echo 22/7 | bc -l

    Usando echo para canalizar la entrada a bc y bc -l

    Si hay espacios en la entrada o desea incluir el comando "escala", escriba la entrada entre comillas.

     echo "22 / 7" | bc -l
    echo "scale=6; 22 / 7" | bc

    Ajustar la entrada incluyendo espacios entre comillas para redirigirla a bc y bc -l

    Usando bc en scripts de shell Bash

    Ahora tenemos todo lo que necesitamos para poder realizar cálculos de punto flotante en nuestros scripts bash, con la precisión que elijamos. También podemos hacer referencia a variables de Bash en nuestros cálculos, incluidos los parámetros del script.

    Aquí está nuestro script de ejemplo. Copie este texto en un editor, guárdelo como "pi.sh" y luego cierre el editor.

     #!/bin/bash

    first_number=22
    second_number=7

    pi=$(echo "scale=$1; $first_number/$second_number" | bc)

    echo "Pi to $1 decimal places is: $pi"

    Usamos dos variables, "primer_número" y "segundo_número" para contener dos valores numéricos. Usamos esas variables en la entrada que estamos conectando a bc.

    También utilizamos el primer parámetro de línea de comando pasado al script, "$1", como valor para establecer "escala".

    Antes de que podamos probar nuestro script, debemos hacerlo ejecutable con chmod.

     chmod +x pi.sh 

    Utilice chmod para hacer ejecutable un script

    Probemos nuestro script con diferentes valores de línea de comando.

     ./pi.sh 5
    ./pi.sh 14
    ./pi.sh 20

    Salida del script pi.sh que muestra pi calculado con tres precisiones diferentes

    Nos mostramos más en la cantidad de posiciones que especificamos en la línea de comando en nuestro script.

    Relacionado: Cómo utilizar getopts para analizar las opciones del script de shell de Linux

    todo suma

    Ir más allá de los límites de las matemáticas de solo números enteros de Bash brinda precisión y exactitud a nuestros scripts.

    Usar echo para canalizar la entrada a bc dentro de los scripts es un poco engorroso, pero funciona perfectamente y vale la pena el esfuerzo.

    Subir Change privacy settings