12.2 Priorité des opérateurs mathématiques |
See You Why? |
Nous venons de voir les opérateurs mathématiques qu'utilise JS.
Cette séquence s'efforcera de vous montrer que JS ne traite pas toutes les opérations avec la même priorité. Ainsi, lorsque différentes opérations mathématiques sont présentes sur une ligne d'instruction, JS ne se contente pas toujours de la lire de gauche à droite comme un autre texte. Nous n'envisagerons ici que les principaux opérateurs mathématiques. Nous aborderons les autres opérateurs dans le chapitre 17, après avoir traité des conditions complexes et multiples.
On pourrait par exemple lire :
17 + 4 - 6 - 5 ;
17 * 4 - (6-5) ;
Si une ligne d'instruction comprend plusieurs additions et/ou soustractions et aucune autre opération ni parenthèses, tous les opérateurs ont la même priorité et les opérations seront exécutées dans l'ordre de leur lecture, c'est-à-dire de gauche à droite :
17 | + 4 | - 6 | - 5 |
21 | - 6 | - 5 | |
15 | - 5 | ||
10 |
Dans l'échelle de précédence ou priorité des opérateurs, addition et soustraction sont au niveau 6.
Dans la séquence précédente, nous avions cependant remarqué que + et - étaient parfois des opérateurs unaires; l'un pour signifier qu'il fallait convertir en valeur numérique une expression qui ne l'était peut-être pas, et l'autre pour signifier qu'il fallait changer le signe de la valeur numérique qui suit. Dans le cas d'opérateurs unaires, la priorité de ces opérateurs n'est plus de 6, mais passe au niveau 4.
De même, si une ligne d'instruction comprend plusieurs multiplications et/ou divisions et aucune autre opération ni parenthèses, tous les opérateurs ont la même priorité et les opérations seront exécutées dans l'ordre de leur lecture, c'est-à-dire de gauche à droite :
17 | * 4 | / 6 | / 5 |
68 | / 6 | / 5 | |
11,333... | / 5 | ||
2,2666... |
Dans l'échelle de précédence ou priorité des opérateurs, multiplication et division sont au niveau 5, donc à une priorité supérieure aux additions et soustractions qui sont au niveau 6.
Une erreur fréquente est l'encodage d'une division par une fraction...
souvent encodé 8 / 15 / 3 / 4
ce qui donnerait 0,5333 / 3 / 4
ou 0,1777 / 4
ou 0,0444
donc erreur...
il ne faut pas oublier que diviser par une fraction, c'est multiplier par la fraction inverse et on peut alors vérifier
que 8 / 15 * 4 / 3
ou 0,533 * 4 / 3
ou 2,1333 / 3
ou 0,7111
ce qui fait bien les 32/45.
Une autre façon correcte d'encoder ce calcul aurait été de faire usage des parenthèses (8 / 15) / (3 / 4)
, ce qui sera expliqué plus bas.
Si une ligne d'instruction comprend plusieurs additions et/ou soustractions et des multiplications et/ou divisions, mais pas de parenthèses, tous les opérateurs n'ont plus la même priorité. En effet, multiplication et division ont une priorité supérieure aux additions et/ou soustractions.
Cela signifie que les multiplications et divisions d'une ligne seront exécutées avant les additions et/ou soustractions de la ligne... et pour chaque niveau de priorité, les opérations seront exécutées dans l'ordre de leur lecture, c'est-à-dire de gauche à droite :
17 | + 4 | * 6 | - 5 | * 2 | * 3 |
17 | + 24 | - 10 | * 3 | ||
17 | + 24 | - 30 | |||
+ 41 | - 30 | ||||
+ 11 |
Cet exemple illustre qu'un opérateur à priorité plus élevée (donc à incice plus bas) sera exécuté avant les opérateurs à priorité plus basse (à indice plus élévé).
Ainsi, s'il n'y a pas de parenthèses, et s'il y a plusieurs des 4 opérations (+, -, x, : ), on effectue les multiplications et divisions en priorité.
Les parenthèses ne sont pas considérées comme des opérateurs, mais elles modifient l'ordre de priorité des opérateurs. En effet, une expression entre parenthèses est toujours évaluée avant que sa valeur propre ne soit utilisée dans l'expression. C'est ce que l'on désigne en parlant de suppression des parenthèses.
De plus, plusieurs parenthèses imbriquées sont possibles dans une même ligne de code. On parle alors de différents niveaux de parenthèses. Dans ce cas, on commence toujours par évaluer l'expression qui se trouve dans les parenthèses les plus internes (c-à-d celles qui se referment en premier lieu).
Les parenthèses sont donc inutiles pour encadrer une expression qui a un opérateur de priorité supérieure ou égale.
On n'écrira donc pas :
rho = (b * b) - 4 * (a * c)
mais
rho = b * b - 4 * a * c
Notre division d'une fraction par une autre fraction (voir titre B. ci-dessus) aurait pu se noter :
(8 / 15) / (3 / 4)
ce qui donnerait 0,5333 / 0,75
soit 0,7111
ce qui fait bien les 32/45.
Depuis la séquence précédente, vous n'ignorez plus ce qu'est l'opérateur 'modulo' qui recherche le reste de la division par...
Ce brave opérateur ne va pas nous compliquer la vie en ce qui concerne sa précédence de priorité, puisqu'il se situe au niveau 5, comme les multiplications et les divisions... Pas besoin donc de multiplier les exemples.
De tous les opérateurs vus jusqu'ici et présentés comme tels, les opérateurs ++ et -- ont la plus grande des priorités (des opérateurs vus jusqu'ici). Ce sont des opérateurs unaires (avec une seule opérande) et ils se situent à un niveau 3 sur l'échelle de précédence, soit une priorité supérieure au + unaire qui signifie 'changer de signe'. C'est dire qu'il s'agit d'opérateurs le plus rapidement effectués lorsqu'ils sont présents dans une instruction.
Donc, quand on écrit :
r = ++a + b * c;
, c'est d'abord prendre l'ancienne valeur de a et l'incrémenter,
puis multiplier b par c,
ensuite faire la somme des résultats partiels (a après incrémentation et produit de b par c)
et enfin affecter la valeur de cette somme à la variable r.
Affectation et affectation spéciale sont aussi considérés comme des opérateurs mathématiques. En effet 'a += 50' veut bien dire :
* tu prends la valeur de a ;
* tu lui ajoutes 50 (addition, calcul d'une somme) ;
* tu attribues à la variable a cette nouvelle somme.
Si vous souhaitez, vous pourriez déterminer vous même la priorité de l'affectation ou des affectations spéciales... à vous de réfléchir avant de répondre.
Priorité basse veut dire indice haut, car plus loin dans la liste des priorités. Les affectations sont au niveau 17 dans l'ordre de priorité. [À ne pas lire avant de répondre au QCM ci-dessus ;o) ]
Attention, JS permet plusieurs affectations (spéciales) dans une même expression. Dans ce cas, les affectations se réalisent de droite à gauche et pas de gauche à droite, comme d'habitude. C'est d'ailleurs normal, puisque chaque fois, on calcule ce qui se trouve à droite du signe = puis on l'affecte à ce qui se trouve à gauche. Ainsi,
Pour A=3 et B=4, l'expression A *= B += 5
sera évaluée comme suit :
1) B prend son ancienne valeur 4 qu'il augmente de 5 et vaut donc 9,
2) A prend son ancienne valeur 3 qu'il multiplie par la nouvelle valeur de B donc 9 et vaudra donc 27.
Attention, nombreuses sont les sources d'erreurs, comme par exemple :
a *= b + 1 |
est équivalent à
|
a = a * (b+1) |
a *= b + 1 |
n'est pas équivalent à
|
a = a * b+1 |
Après l'étude des opérateurs logiques, nous finirons cette liste de précédence d'opérateurs mathématiques, de comparaison et logiques. Nous pourrons alors vérifier des expressions aussi bizarres que:
condition = age == 10 + 8 && nationalite == "DZ" || nationalité =="BE";
ou encore
condition = ((4 >= 6) || ("vin" != "rouge")) && !(((12 * 2) == 144) && true);
Patience, c'est prévu au chapitre 17, séquence relative à la précédence de tous les opérateurs.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
voir suite >>>
voir suite >>>