web-dev-qa-db-fra.com

Quelle est la sémantique exacte des opérateurs de quart de travail de Rust?

J'ai essayé de trouver des informations précises sur la façon dont << et >> les opérateurs travaillent sur des entiers, mais je n'ai pas pu trouver de réponse claire ( la documentation n'est pas très bien à cet égard).

Il y a deux parties de la sémantique qui ne sont pas claires pour moi. Premièrement, quels bits sont "décalés"?

  • Les zéros sont décalés d'un côté (c'est-à-dire 0b1110_1010u8 << 4 == 0b1010_0000u8), ou
  • les bits tournent (c'est-à-dire 0b1110_1010u8 << 4 == 0b1010_1110u8), ou
  • il n'est pas spécifié (comme le comportement de débordement d'entiers n'est pas spécifié), ou
  • autre chose.

De plus, comment les changements fonctionnent-ils avec les entiers signés? Le bit de signe est-il également impliqué dans le changement ou non? Ou est-ce non spécifié?

14
Lukas Kalbertodt

Quelle est la sémantique exacte des opérateurs de quart de travail de Rust?

Il n'y en a pas. Les opérateurs de décalage sont un trait implémentable par l'utilisateur et vous pouvez faire essentiellement tout ce que vous voulez en eux. La documentation montre même un exemple de "[a] n implémentation de Shr qui fait tourner un vecteur vers la droite d'un montant donné".


comment le << et >> les opérateurs travaillent sur des entiers,

La référence a une section sur Opérateurs binaires arithmétiques et logiques . Plus utilement, il contient cette note de bas de page:

Décalage à droite arithmétique sur les types entiers signés, décalage à droite logique sur les types entiers non signés.

décalage logique et décalage arithmétique sont des termes informatiques préexistants avec des définitions établies.

Les zéros sont décalés

Oui.

les bits tournent

Non. Il existe des méthodes distinctes pour faire pivoter gauche et droite .

10
Shepmaster

La documentation fine sur les traits Shl et Shr est intentionnelle, afin qu'ils adoptent un comportement qui convient le mieux au type en question (pensez aux nouveaux types!).

Cela dit, en ce qui concerne les types entiers de base, la référence Rust couvre leur comportement, avec un peu d'inférence:

  • << | Décalage à gauche | std::ops::Shl

  • >> | Maj droite * | std::ops::Shr

* Décalage à droite arithmétique sur les types entiers signés, décalage à droite logique sur les types entiers non signés.

Il comprend également quelques exemples, qui clarifient davantage qu'il s'agit de décalages logiques/arithmétiques conventionnels: des zéros sont insérés dans les bits les moins significatifs sur un décalage de bits gauche, et le bit le plus significatif est étendu pour les entiers signés sur un décalage de bits droit. C'est aussi pas une rotation , comme décrit dans les méthodes rotate_left et rotate_right.

assert_eq!(13 << 3, 104);
assert_eq!(-10 >> 2, -3);

De plus, décaler trop de bits peut être considéré comme un débordement arithmétique et n'est pas un comportement indéfini. Voir: Est-il prévu qu'un décalage de bits trop important soit un comportement indéfini dans Rust?

9