Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Priorité et associativité des opérateurs

125 réponses
Avatar
Greydavayar
Bonjour a tous,

je lis partout le terme "d'associativit=E9" des op=E9rateurs ainsi que le
teme de "priorit=E9" des op=E9rateurs je pense avoir compris celui de la
priorit=E9 mais cette notion d'associativit=E9 reste tr=E8s (trop) floue
pour moi et je ne trouve rien qui l'explique clairement sur le net.

Bonne soir=E9e

10 réponses

Avatar
Lucas Levrel
Le 9 septembre 2010, Alexandre Bacquart a écrit :

Par contre, je crois que des formulation comme (a-b)-c ou a-(b+c) sont
effectivement auto-documentées, rajoutant explicitement une information
C'est surtout vrai lorsque, comme dans le premier cas, elles sont
syntaxiquement inutiles, donc n'ont de portée sémantique qu'à
destination de celui qui lit, comme n'importe quel commentaire.



Je partage ton avis sur le premier cas, mais pour le deuxième, c'est le
changement d'expression qui est susceptible de me gêner dans certains
contextes. J'ai bien dit "susceptible".



Il me semble que le point de vue de JKB est : a-b-c montre que le
programmeur ne s'est pas posé la question des cas limites, contrairement à
a-(b+c) ou (a-b)-c. Les deux dernières sont donc préférables à la
première, mais (et il me semble que c'est ce sur quoi tu insistes) un
mainteneur ne devrait pas remplacer a-b-c par a-(b+c) *uniquement* pour
améliorer la lisibilité, il ne peut pas se passer de scruter les cas
limites.

Oui, le résultat est le même puisqu'on est dans R (passons le fait que
strictement, l'équivalence est fausse et qu'on est pas totalement dans R,
inutile d'alourdir le débat ici avec des UB de magnitudes ou de
débordements), mais à mes yeux, l'expression est *différente* avant d'être
*formelle et préférable*.



Dans R, a-b-c=a-(b+c) et quelqu'un qui utilise couramment les maths
n'interprétera pas différemment les deux formes.

La différence cruciale apparaît en analyse numérique avec les cas limites,
qui ne sont absolument pas des /undefined behaviours/ soit dit en
passant !

Et je sais tout cela depuis longtemps. Je suis précisément, en ce moment,
dans ce bain là, notamment en ce qui concerne les flottants car j'ai
justement besoin de représenter des quantités astronomiques (de l'ordre de
l'année-lumière par rapport au centimètre) et étant donné mes pré-requis, je
vais devoir tricher (les doubles ne résolvent pas le problème).



Et les long double ? Sur mon système LDBL_DIG=.

--
LL
Avatar
Pierre Maurette
JKB, le 09/09/2010 a écrit :

[...]

Lorsque tu écris a - b - c, tu ne sauras _jamais_ si le type qui a
codé ça l'a fait en toute connaissance de cause alors que si tu
avais (a - b) - c ou a - (b + c), tu n'aurais plus aucun doute.



Et si /le type/ code (a - b - c), vous en déduisez que logiquement:
- /le type/ a codé /en toute connaissance de cause/.
- /le type/ est un peu tordu, ou simplement mutin.
?

--
Pierre Maurette
Avatar
Wykaaa
Lucas Levrel a écrit :
Le 9 septembre 2010, Alexandre Bacquart a écrit :

Par contre, je crois que des formulation comme (a-b)-c ou a-(b+c) sont
effectivement auto-documentées, rajoutant explicitement une information
C'est surtout vrai lorsque, comme dans le premier cas, elles sont
syntaxiquement inutiles, donc n'ont de portée sémantique qu'à
destination de celui qui lit, comme n'importe quel commentaire.



Je partage ton avis sur le premier cas, mais pour le deuxième, c'est
le changement d'expression qui est susceptible de me gêner dans
certains contextes. J'ai bien dit "susceptible".



Il me semble que le point de vue de JKB est : a-b-c montre que le
programmeur ne s'est pas posé la question des cas limites, contrairement
à a-(b+c) ou (a-b)-c. Les deux dernières sont donc préférables à la
première, mais (et il me semble que c'est ce sur quoi tu insistes) un
mainteneur ne devrait pas remplacer a-b-c par a-(b+c) *uniquement* pour
améliorer la lisibilité, il ne peut pas se passer de scruter les cas
limites.

Oui, le résultat est le même puisqu'on est dans R (passons le fait que
strictement, l'équivalence est fausse et qu'on est pas totalement dans
R, inutile d'alourdir le débat ici avec des UB de magnitudes ou de
débordements), mais à mes yeux, l'expression est *différente* avant
d'être *formelle et préférable*.



Dans R, a-b-c=a-(b+c) et quelqu'un qui utilise couramment les maths
n'interprétera pas différemment les deux formes.



Il ne faut pas confondre l'ensemble R des réels en mathématique et les
nombres flottants en programmation. Les deux domaines n'ont pas
grand-chose en commun. La première chose que nous a dite le prof
d'informatique, à la première heure de cours (c'était en 1970 pour ce
qui me concerne) c'est : "vous pouvez demander beaucoup de choses à un
ordinateur mais pas de stocker racine carrée de 2". Il n'y a pas de
nombres irrationnels en informatique !

Quand on écrit a-b-c, normalement, puisque l'opération est associative à
gauche, les calculs se feront comme si on avait écrit : (a-b)-c
(soustraction de b à a puis soustraction de c au résultat.
Si on écrit a-(b+c), ceci n'a rien à voir avec le calcul précédent car
l'ordre de calcul est le suivant :
addition de b+c puis soustraction de ce résultat à a.
L'addition b+c peut engendrer un overflow qui ne peut se produire avec
l'écriture précédente !
Du point de vue de l'exécution, les deux écritures sont très
différentes. D'ailleurs, un optimiseur est parfaitement en droit, pour
l'expression a-b-c, de calculer (a-c)-b mais il ne devrait pas se
permettre de calculer cette expression de la façon a-(b+c).
Cependant, et les gens du calcul numérique le savent bien, si l'on veut
que les calculs soient exécutés exactement comme on les a écrits, il faut :
1) décomposer toute expression au maximum
2) débrayer toute option d'optimisation à la compilation

La différence cruciale apparaît en analyse numérique avec les cas
limites, qui ne sont absolument pas des /undefined behaviours/ soit dit
en passant !

Et je sais tout cela depuis longtemps. Je suis précisément, en ce
moment, dans ce bain là, notamment en ce qui concerne les flottants
car j'ai justement besoin de représenter des quantités astronomiques
(de l'ordre de l'année-lumière par rapport au centimètre) et étant
donné mes pré-requis, je vais devoir tricher (les doubles ne résolvent
pas le problème).



Et les long double ? Sur mon système LDBL_DIG=.



Les long double ne sont pas portables en C.
Il existe des librairies qui savent effectuer les calculs en précision
arbitraire comme MPFR
(http://interstices.info/jcms/c_9345/mpfr-vers-un-calcul-flottant-correct?portal=j_97&printView=true).
Avatar
Vincent Lefevre
Dans l'article <i682vb$98r$,
Antoine Leca écrit:

Cela dépend complètement des gens : beaucoup de programmeurs C se
plaignent et préféreraient le contraire, que & (et aussi << et >>)
soient plus prioritaires qu'ils ne le sont en C. En particulier plus
prioritaires que les opérateurs de comparaison, comme dans
if (a&mask == b&mask) /* effet surprenant en C... */



Oui, et heureusement que le C n'a pas d'opérateur puissance.

Mais la précédence du - unaire sur * et / est aussi surprenante.

--
Vincent Lefèvre - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Avatar
JKB
Le Thu, 09 Sep 2010 11:17:24 +0200,
Pierre Maurette écrivait :
JKB, le 09/09/2010 a écrit :

[...]

Lorsque tu écris a - b - c, tu ne sauras _jamais_ si le type qui a
codé ça l'a fait en toute connaissance de cause alors que si tu
avais (a - b) - c ou a - (b + c), tu n'aurais plus aucun doute.



Et si /le type/ code (a - b - c), vous en déduisez que logiquement:
- /le type/ a codé /en toute connaissance de cause/.
- /le type/ est un peu tordu, ou simplement mutin.
?



J'en déduis la même chose que pour a - b - c. Les opérations
prennent naturellement deux opérandes. Si on ne veut pas avoir de
(mauvaises) surprises, on colle des parenthèses ou on décompose le
calcul

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Avatar
Wykaaa
Vincent Lefevre a écrit :
Dans l'article <i682vb$98r$,
Antoine Leca écrit:

Cela dépend complètement des gens : beaucoup de programmeurs C se
plaignent et préféreraient le contraire, que & (et aussi << et >>)
soient plus prioritaires qu'ils ne le sont en C. En particulier plus
prioritaires que les opérateurs de comparaison, comme dans
if (a&mask == b&mask) /* effet surprenant en C... */



Oui, et heureusement que le C n'a pas d'opérateur puissance.

Mais la précédence du - unaire sur * et / est aussi surprenante.



Dans quasiment tous les langages de programmation les opérateurs unaires
sont plus prioritaires que les opérateurs d'arité supérieure.
Quoi qu'il en soit, je ne comprends pas pourquoi tu dis que c'est
"surprenant".
Avatar
Vincent Lefevre
Dans l'article <4c88a7b5$0$10199$,
Wykaaa écrit:

Il ne faut pas confondre l'ensemble R des réels en mathématique et les
nombres flottants en programmation. Les deux domaines n'ont pas
grand-chose en commun. La première chose que nous a dite le prof
d'informatique, à la première heure de cours (c'était en 1970 pour ce
qui me concerne) c'est : "vous pouvez demander beaucoup de choses à un
ordinateur mais pas de stocker racine carrée de 2". Il n'y a pas de
nombres irrationnels en informatique !



Tout dépend de l'arithmétique utilisée. Avec iRRAM, aucun problème
pour manipuler les irrationnels, qui sont représentés *exactement*
par des arbres de calcul.

--
Vincent Lefèvre - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Avatar
Samuel DEVULDER
Le 09/09/2010 11:24, Wykaaa a écrit :

La première chose que nous a dite le prof
d'informatique, à la première heure de cours (c'était en 1970 pour ce
qui me concerne) c'est : "vous pouvez demander beaucoup de choses à un
ordinateur mais pas de stocker racine carrée de 2". Il n'y a pas de
nombres irrationnels en informatique !



<mode mutin=on>Peut de temps après sortait MuMath sur Apple2 et montrait:
1- qu'il avait tord dans les faits: les ordis savent parfaitement
stocker et manipuler sqrt(2) très exactement.
2- qu'un exemple n'a qu'une n'est qu'un exemple et pas une vérité
définitive à prendre au pied de la lettre. Il ne sert qu'à fixer l'esprit.
</mode>

Je cite MuMath sur Apple2 car c'est le 1er sur lequel je suis tombé
perso, mais je suis même sur que des systèmes formels capable de
travailler avec des racines de polynômes devaient exister avant lui.

Cela dit ton prof n'avait pas tord dans l'esprit.. Seul l'exemple était
trop simpliste. Et puis pour une 1ere heure de cours c'est suffisant. :-p

sam.
Avatar
Vincent Lefevre
Dans l'article <4c88b292$0$5433$,
Wykaaa écrit:

Dans quasiment tous les langages de programmation les opérateurs unaires
sont plus prioritaires que les opérateurs d'arité supérieure.
Quoi qu'il en soit, je ne comprends pas pourquoi tu dis que c'est
"surprenant".



Parce que c'est contraire à l'écriture mathématique. En C, le problème
est peu visible, car il n'y a pas d'opérateur puissance, mais dans un
langage avec ^ qui signifie puissance, je m'attends à ce que -3^2
donne -9 et non 9 (surtout dans les logiciels de calcul formel), car
c'est la règle mathématique.

En C, je m'attendrais à ce que - a * b et 0 - a * b donnent la même
chose (en supposant a * b non nul), mais si le mode d'arrondi est
vers -inf ou +inf, il peut y avoir une différence.

--
Vincent Lefèvre - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Avatar
JKB
Le Thu, 9 Sep 2010 10:32:33 +0000 (UTC),
Vincent Lefevre écrivait :
Dans l'article <4c88b292$0$5433$,
Wykaaa écrit:

Dans quasiment tous les langages de programmation les opérateurs unaires
sont plus prioritaires que les opérateurs d'arité supérieure.
Quoi qu'il en soit, je ne comprends pas pourquoi tu dis que c'est
"surprenant".



Parce que c'est contraire à l'écriture mathématique. En C, le problème
est peu visible, car il n'y a pas d'opérateur puissance, mais dans un
langage avec ^ qui signifie puissance, je m'attends à ce que -3^2
donne -9 et non 9 (surtout dans les logiciels de calcul formel), car
c'est la règle mathématique.

En C, je m'attendrais à ce que - a * b et 0 - a * b donnent la même
chose (en supposant a * b non nul), mais si le mode d'arrondi est
vers -inf ou +inf, il peut y avoir une différence.



C'est là qu'on se dit que la notation polonaise inversée a du bon
;-)

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr