Je sais que le comportement de >>
sur l’entier signé peut dépendre de l’implémentation (en particulier lorsque l’opérande gauche est négatif).
Qu’en est-il des autres: ~
, >>
, &
, ^
, |
? Lorsque leurs opérandes sont des entiers signés de type intégré ( short
, int
, long
, long long
), les résultats sont-ils garantis identiques (en termes de contenu bit) si leur type est non signé?
Pour les opérandes négatifs, <<
a un comportement indéfini et le résultat de >>
est défini par l'implémentation (généralement comme décalage droit "arithmétique"). <<
et >>
sont conceptuellement des opérateurs non binarys. Ce sont des opérateurs arithmétiques équivalents à la multiplication ou à la division par la puissance appropriée de deux pour les opérandes sur lesquels ils sont bien définis.
Quant aux véritables opérateurs binarys ^
, ~
, |
et &
, ils opèrent sur la représentation bit de la valeur dans le type (éventuellement promu) de l'opérande. Leurs résultats sont bien définis pour chaque choix possible de représentation signée (complément à deux, complément à un, ou grandeur de signe) mais dans les deux derniers cas, il est possible que le résultat soit une représentation de piège si l'implémentation traite le "zéro négatif" la représentation comme un piège. Personnellement, j'utilise presque toujours des expressions non signées avec des opérateurs binarys, de sorte que le résultat est bien défini en termes de valeurs plutôt que de représentations .
Enfin, notez que cette réponse, telle qu'elle est écrite, ne peut s'appliquer qu'à C. C et C ++ sont des langages très différents et bien que je ne connaisse pas bien le C ++, je comprends que cela puisse différer de C ...
<<
d'une valeur négative a un comportement indéfini; >>
d'une valeur négative donne un résultat défini par l'implémentation; &
, |
et ^
opérateurs sont définis en termes de représentation binary des valeurs. Trois possibilités sont possibles pour la représentation des nombres négatifs dans C: le complément à deux, le complément et la magnitude du signe. La méthode utilisée par l'implémentation déterminera le résultat numérique lorsque ces opérateurs sont utilisés sur des valeurs négatives. Notez que la valeur avec le bit de signe 1 et tous les bits de valeur zéro (pour le complément à deux et la magnitude de signe), ou avec le bit de signe et tous les bits de valeur 1 (pour le complément) est explicitement autorisée. Si vous utilisez des arguments pour ces opérateurs qui génèrent une telle valeur, le comportement est indéfini.
Le contenu du bit sera le même, mais les valeurs obtenues dépendront toujours de la mise en œuvre.
Vous ne devriez vraiment pas voir les valeurs comme signées ou non signées lorsque vous utilisez des opérations au niveau du bit, car cela fonctionne à un niveau différent.
L’utilisation de types non signés vous évite certains de ces problèmes.
La norme C89 définit le comportement des nombres signés décalés vers la gauche en fonction des positions des bits. Si ni les types signés ni les types non signés ne comportent de bits de remplissage, le comportement requirejs pour les types non signés, associé à la nécessité que les types de signes positifs partagent la même représentation que les types non signés, impliquerait que le bit de signe se trouve immédiatement à gauche du bit de valeur le plus significatif .
Ceci, en C89, -1 << 1 serait -2 sur les implémentations à deux complément qui n'ont pas de bits de remplissage et -3 sur les implémentations complémentaires de ceux qui n'ont pas de bits de remplissage. S'il y a des implémentations d'amplitude de signe sans bits de remplissage, -1 << 1 serait égal à 2.
La norme C99 a changé les décalages à gauche des valeurs négatives en Comportement non défini, mais rien dans la justification ne permet de savoir pourquoi (ou mentionne même le changement). Le comportement requirejs par C89 était peut-être moins qu’idéal dans les implémentations de certains, et il serait donc logique d’autoriser ces implémentations à choisir quelque chose de mieux. Je n’ai vu aucune preuve suggérant que les auteurs de la norme ne pensaient pas que les implémentations de qualité à complément à deux devraient continuer à offrir le même comportement que C89, mais elles ne l’ont malheureusement pas dit.