Outils pour utilisateurs

Outils du site


cours:informatique:fun_mooc:maitrise_du_bash_univ-reunion:340_calculs_numeriques

Bash: calculs numériques

Par défaut le Bash traite toutes les valeurs comme des chaînes de caractères. Plusieurs solutions existent pour effectuer des opérations arithmétiques.

Commande expr

expr est une commande qui prend pour arguments chaque terme de l'expression arithmétique. Pour évaluer correctement cette expression, chaque opérande et chaque opérateur doit être séparé par un espace:

# Pour que expr puisse interpréter correctement l'expression
# chaque opérande et opérateurs de l'expression mathématique
# doivent être des arguments séparés
$ expr 3 + 2
5
 
# Attention a bien inhiber le métacaractère '*' qui a une signification
# pour le shell. Il ne doit pas être interprété et passé tel quel à la 
# commande expr 
$ expr 3 \* 2
6
 
# Ici expr est invoquée sans séparer les termes. Un seul argument
# sans signification pour expr, il n'est pas évalué
$ expr 3+2 
3+2
 
# Les parenthèses sont des caractères spéciaux pour le shell.
# Il faut donc empêcher le shell de les traiter.
$ expr \( 10 + 6 \) / 2
8

expr est une commande externe, son choix est pertinent lorsque des contraintes de portabilité du code existent.

Substitution arithmétique

Le shell Bash est capable d'évaluer une expression arithmétique et de la substituer par le résultat. La syntaxe de la substitution arithmétique en Bash:

$(( expression ))

Elle présente quelques avantages:

  • Les termes de l’expression n’ont plus besoin d’être séparés par des espaces.
  • L’usage d’une variable s’effectue sans la préfixer par le caractère $.
  • Les caractères spéciaux du shell ne sont pas interprétés.
  • La commande est interne au shell. Elle s’exécute dans le même processus que le shell lui-même.
$ a=2 ; b=3
$ i=$((a*b))
$ echo $i
6

Commande interne let

Les expressions arithmétiques sont évaluées par la commande interne let “expression” qui s’abrège via la syntaxe ((expression)). Contrairement à la substitution arithmétique la commande let n’effectue aucune sortie. Ainsi l’expression peut être une affectation sans provoquer d’erreur:

# affectation avec let
((i=1+2))
 
# L'usage de la substitution arithmétique pour cette même
# affectation provoque une erreur car après substitution,
# le shell essai d’interpréter le résultat qui n'est pas
# une commande valide
$((i=1+2))
2 : commande introuvable
 
# usages équivalents
let "a=a+1"
let "a+=1"
((a++))
Attention de ne pas confondre la commande let abrégée (( )) avec la substitution arithmétique $(( )). La substitution remplace l’expression par le résultat de son évaluation, alors que la commande (( )) se comporte comme son nom l’indique comme une commande sur une ligne de commande. De plus elle n’affiche aucun résultat.

La commande let permet de faire davantage que des calculs sur des entiers. Comme toutes les commandes des systèmes Unix, une fois exécutée la commande retourne un code d’état dans la variable $?. Lorsque l’expression est une expression booléenne, le code retour prend la valeur 0 pour les cas où l’évaluation de l’expression a pour valeur vraie.

$ a=33
$ ((a==12))
$ echo $?
1

Déclaration d'une variable de type entier

Par défaut les valeurs manipulées par le shell sont des chaîne de caractères. Il est cependant possible de déclarer une variable de type entier relatif. Avec les variables typées entier, il sera possible d’effectuer des opérations arithmétiques sans avoir recours aux commandes expr ou let.

$ declare -i b=33
$ b=b+3
$ echo $b
36
A propos de la syntaxe: Comme on peut le voir ci-dessus, dans une expression arithmétique, on peut manipuler les valeurs des variables de type entier sans précéder le label de la variable avec $.

Outre une évaluation implicite (sans avoir recours à la commande let), la déclaration de variable assure que la valeur est toujours un entier (relatif). Si une chaîne de caractères non numérique est affectée, la conversion en valeur entière donnera la valeur 0.

$ declare -i a
$ a=essai
$ echo $a
0

Calculs sur des nombres décimaux

expr et le shell peuvent faire des calculs sur des nombres entiers. Dans l’utilisation courante d’un shell qui vise à faire des comptages, c’est bien suffisant. Mais s’il est nécessaire de faire des calculs scientifiques, il faut avoir recours à la commande dédiée bc.

bc peut être utilisée en mode interactif ou en mode commande.

# invoque bc en mode interactif sans affichage
# de la bannière d'accueil
$ bc -q
 
# Invoquer bc en mode commande en fournissant les
# commandes sur son entrée standard.
# NB: Pour prendre en compte les décimales, il faut spécifier
# la précision par la directive scale. En indiquant scale=10,
# la commande bc codera les nombres sur une précision de 10 décimales.
$ b=10
$ echo "scale=5 ; $b/3" | bc
3.33333
cours/informatique/fun_mooc/maitrise_du_bash_univ-reunion/340_calculs_numeriques.txt · Dernière modification : 2022/01/14 14:28 de yoann