Comment faire des mathématiques à virgule flottante dans les scripts Linux Bash


Points clés à retenir

  • Le shell Linux Bash ne prend en charge que l’arithmétique entière et ne peut pas effectuer de calculs sur des nombres à virgule flottante.
  • L’utilitaire bc sous Linux permet des calculs de précision en virgule flottante de manière interactive et dans des scripts shell.
  • En utilisant bc, vous pouvez définir le nombre de décimales à afficher et effectuer des calculs avec une précision arbitraire, notamment en utilisant les fonctions de la bibliothèque mathématique standard.


Le shell Linux Bash prend en charge uniquement l’arithmétique des nombres entiers. Il ne peut ni comprendre ni gérer les calculs en virgule flottante. L’utilitaire bc vous offre des calculs précis en virgule flottante de manière interactive et dans des scripts shell.


Pourquoi Bash ne prend en charge que les entiers

La décision de conception originale de restreindre la Unix Coquille Bourne arithmétique entière pourrait être enraciné dans le mappage informatique précoce d’un entier sur un seul octet de RAM. Nous ne saurons peut-être jamais ce qui se cache réellement derrière cette décision. Ni d’ailleurs pourquoi la version Linux du shell Bourne, le shell Bash, a choisi de emboîter le pas.

À lui seul, Bash ne peut pas effectuer de calculs sur des nombres à virgule flottante, et les calculs sur des nombres entiers qui auraient une partie fractionnaire dans la réponse sont signalés sous forme de valeurs entières tronquées. Cela est vrai sur la ligne de commande et dans les scripts shell Bash. Selon votre cas d’utilisation, cela peut être problématique ou époustouflant.

Linux est livré avec deux applications utilitaires qui vous permettent d’effectuer des calculs en virgule flottante. L’un d’eux est DC. C’est un peu une curiosité, fonctionnant comme dans notation polonaise inversée. L’autre outil est bc. Il peut être utilisé de manière interactive ou sous forme de commande, et c’est la solution dont nous parlerons ici.

Connexe : 9 exemples de scripts Bash

Le problème

Laissons Bash diviser six par trois.

 echo $((6 / 3)) 
Diviser deux entiers sans reste sur la ligne de commande Bash

Nous obtenons notre réponse attendue de deux. Maintenant, divisons six par sept. De toute évidence, cela aura une réponse fractionnaire.

 echo $((6 / 7)) 
Diviser deux entiers sur la ligne de commande Bash avec un reste fractionnaire.  Le reste n'est jamais affiché.

Zéro est évidemment faux. Essayons à nouveau en divisant 16 par 7.

 echo $((16 / 7)) 
Illustrant le problème avec BAsh ne prenant en charge que l'arithmétique des nombres entiers en divisant deux nombres entiers.  Le reste fractionnaire est écarté.

Nous obtenons une réponse de deux. Ce qui se passe, c’est que la partie fractionnaire de la réponse est rejetée, la réponse est donc tronquée. Il n’y avait pas de partie fractionnaire dans le premier exemple, nous obtenons donc la bonne réponse.

Le deuxième exemple ne contenait aucun élément entier dans la réponse, seulement une partie fractionnaire. Parce que la partie fractionnaire a été supprimée, la réponse qui nous est présentée est zéro.

Dans le troisième exemple, 7 se divise deux fois en 16, avec un reste fractionnaire. Là encore, le reste est ignoré et le résultat est tronqué.

Utiliser bc de manière interactive

Vous pouvez utiliser bc comme calculatrice interactive en tapant bc et en appuyant sur la touche « Entrée ».

 bc 
Le message et l'invite de bienvenue de BC

L’application bc se lance, annonce son numéro de version, puis attend votre contribution. En tapant un calcul et en appuyant sur « Entrée », bc évalue le calcul et affiche la réponse.

 16 * 4

1024 / 32

2^2 * 1024

Trois exemples de calculs en bc, en mode interactif

Vous pouvez utiliser « Ctrl+L » pour effacer l’écran et « Ctrl+D » pour quitter le programme. Essayons un calcul qui aura une composante fractionnaire dans la réponse.

 22 / 7 
bc affiche par défaut aucune décimale.  Pi est tronqué à 3.

Ce n’est pas ce à quoi nous nous attendions. Contre-intuitivement, bien que bc nous permette d’utiliser une précision arbitraire, par défaut, il n’affichera pas le point décimal ni les chiffres qui le suivent.

Pour rendre visible la vraie réponse, nous devons indiquer à bc combien de décimales afficher. Nous faisons cela avec la commande « scale ». Nous demanderons sept décimales et refaire notre calcul.

 scale=7
22 / 7
Utiliser l'échelle pour indiquer à bc d'afficher jusqu'à 7 décimales dans les résultats des calculs

Enfin, nous arrivons à quelque chose. Le paramètre « échelle » reste en place jusqu’à ce que vous le modifiiez. La définition du nombre de décimales indique à BC le maximum nombre d’endroits à afficher. Si une réponse ne nécessite pas autant de décimales, elle est affichée avec le nombre de décimales requis et pas plus. Il n’est pas complété par des zéros dénués de sens.

 scale=10
0.300003 * 0.5
bc affiche uniquement les décimales dont il a besoin.  Définir l’échelle sur 10 ne forcera pas l’utilisation de 10 décimales.  Si une réponse nécessite moins de décimales, ce sont les seules qui sont affichées.

Vous pouvez lister différents calculs sur la même ligne en utilisant un point-virgule « ; » pour les séparer. Les réponses sont affichées par ligne comme d’habitude, dans l’ordre dans lequel les calculs ont été répertoriés.

 25 * 6; 12.5 + 45.001; 3 + 5 + 7 + 9 
Vous pouvez ajouter plusieurs calculs à une ligne en les séparant par des points-virgules.

Vous pouvez également inclure la commande « scale » dans la liste.

 scale=8; 22 / 7; scale=3; 0.3 * 0.071 
Vous pouvez modifier le paramètre d'échelle pour chaque calcul, même les calculs sur la même ligne de commande

La bibliothèque mathématique standard

L’option -l (bibliothèque mathématique standard) amène bc à charger un ensemble de fonctions et définit « échelle » à 20 décimales.

 bc -l
22 / 7
bc lancé avec l'option -l, affichant pi calculé avec 20 décimales

Une fois la bibliothèque standard chargée, vous pouvez utiliser ces fonctions dans vos calculs.

  • s (x): Le sinus de x
  • c (x): Le cosinus de x.
  • un (x): L’arctangente de x
  • je (x): Le logarithme népérien de x
  • ex): L’exponentielle de e à la valeur x
  • j (n, x): La fonction Bessel d’ordre entier n de x.

Le sinus, le cosinus et l’arctangente utilisent des valeurs en radian.

 s (1.1)
 
c (.891207)
 
a (.628473)
Calcul du sinus, du cosinus et de l'arctan en bc en mode interactif

Envoi d’une entrée à bc sur la ligne de commande

Vous pouvez utiliser la redirection et les canaux pour envoyer des entrées à bc. Il traite votre saisie et affiche la réponse dans la fenêtre du terminal.

Vous pouvez rediriger vers bc avec ou sans l’option -l (bibliothèque mathématique standard).

 bc <<< 22/7
bc -l <<< 22/7
Redirection des entrées vers bc et bc -l

Pour rediriger l’entrée vers bc, l’entrée doit être la sortie d’un autre processus. Il est pratique d’utiliser echo pour cela.

 echo 22/7 | bc
echo 22/7 | bc -l
Utiliser echo pour diriger l'entrée vers bc et bc -l

Si vous avez des espaces dans votre entrée ou si vous souhaitez inclure la commande « scale », placez votre entrée entre guillemets.

 echo "22 / 7" | bc -l
echo "scale=6; 22 / 7" | bc
Envelopper l'entrée qui inclut des espaces entre guillemets pour la diriger vers bc et bc -l

Utilisation de bc dans les scripts Bash Shell

Nous avons maintenant tout ce dont nous avons besoin pour pouvoir effectuer des calculs en virgule flottante dans nos scripts bash, avec la précision que nous avons choisie. Nous pouvons également référencer des variables Bash dans nos calculs, y compris les paramètres du script.

Voici notre exemple de script. Copiez ce texte dans un éditeur, enregistrez-le sous « pi.sh », puis fermez votre éditeur.

 #!/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"

Nous utilisons deux variables, « first_number » et « second_number » pour contenir deux valeurs numériques. Nous utilisons ces variables dans l’entrée que nous redirigeons vers bc.

Nous avons également utilisé le premier paramètre de ligne de commande transmis au script, « $1 », comme valeur à laquelle définir « scale ».

Avant de pouvoir essayer notre script, nous devons le rendre exécutable avec chmod.

 chmod +x pi.sh 
Utiliser chmod pour rendre un script exécutable

Essayons notre script avec différentes valeurs de ligne de commande.

 ./pi.sh 5
./pi.sh 14
./pi.sh 20
Sortie du script pi.sh montrant pi calculé avec trois précisions différentes

Nous obtenons pi affiché au nombre d’endroits que nous spécifions sur la ligne de commande de notre script.

Connexe : Comment utiliser getopts pour analyser les options de script Linux Shell

Tout s’additionne

Aller au-delà des limites des mathématiques de Bash utilisant uniquement des nombres entiers confère à nos scripts précision et exactitude.

Utiliser echo pour diriger l’entrée vers bc dans les scripts est un peu maladroit, mais cela fonctionne parfaitement bien et les avantages en valent la peine.



Vous pouvez lire l’article original (en Angais) sur le blogwww.howtogeek.com