c - restreint - en binaire



Bit-shift arithmétique sur un entier signé (3)

Comme d'autres l'ont dit, le changement de valeur négative est défini par la mise en œuvre.

La plupart des implémentations traitent le décalage droit signé comme plancher (x / 2 N ) en remplissant des bits décalés en utilisant le bit de signe. C'est très pratique dans la pratique, car cette opération est si commune. D'un autre côté, si vous changez d'entier non signé à droite, les bits décalés seront mis à zéro.

Du point de vue de la machine, la plupart des implémentations ont deux types d'instructions shift-right:

  1. Un décalage 'arithmétique' à droite (ayant souvent un ASR mnémonique ou SRA) qui fonctionne comme expliqué.

  2. Un changement de logique à droite (souvent avec mnémonique LSR ou SRL ou SR) qui fonctionne comme prévu.

La plupart des compilateurs utilisent d'abord pour les types signés et la seconde pour les non signés. Juste pour plus de commodité.

J'essaie de comprendre comment exactement les opérateurs de décalage de bits arithmétiques fonctionnent en C, et comment cela affectera les entiers 32 bits signés.

Pour simplifier les choses, disons que nous travaillons dans un octet (8 bits):

x = 1101.0101
MSB[ 1101.0101 ]LSB

En lisant les autres posts sur Stack Overflow et certains sites, j'ai trouvé que: << va se déplacer vers MSB (vers la gauche, dans mon cas), et remplir les bits LSB "vides" avec 0s.

Et >> va se déplacer vers LSB (vers la droite, dans mon cas) et remplir les bits "vides" avec MS bit

Ainsi, x = x << 7 entraînera le déplacement de LSB vers MSB, et tout mettre à 0s.

1000.0000

Maintenant, disons que je voudrais >> 7 , dernier résultat. Cela entraînerait [0000.0010] ? Ai-je raison?

Ai-je raison de mes hypothèses concernant les opérateurs de quarts?

Je viens de tester sur ma machine, **

int x = 1;   //000000000......01

x = x << 31; //100000000......00

x = x >> 31; //111111111......11 (Everything is filled with 1s !!!!!) 

Pourquoi?


Dans le compilateur 32 bits

x = x >> 31;

ici x est l'entier signé donc le 32ème bit est le bit de signe.

La valeur x finale est 100 000 ... 000 . et le 32ème bit indique la valeur -ive.

Ici, la valeur de x est mise en œuvre pour le compliment de 1.

puis la finale x est -32768


Les opérations de décalage bit à bit ne sont pas définies pour les valeurs négatives

pour '<<'

6.5.7 / 4 [...] Si E1 a un type signé et une valeur non négative, et si E1 × 2 E2 est représentable dans le type de résultat, alors c'est la valeur résultante; sinon, le comportement est indéfini.

et pour '>>'

6.5.7 / 5 [...] Si E1 a un type signé et une valeur négative, la valeur résultante est définie par l'implémentation.

C'est une perte de temps d'étudier le comportement de ces opérations sur des nombres signés sur une implémentation spécifique, car vous n'avez aucune garantie que cela fonctionnera de la même manière sur toute autre implémentation (une implémentation est, par exemple, compilateur sur votre ordinateur avec votre paramètres de ligne de communication spécifiques).

Il pourrait même ne pas fonctionner pour une version plus ancienne ou plus récente du même compilateur. Le compilateur pourrait même définir ces bits comme aléatoires ou indéfinis. Cela signifierait que la même séquence de code pourrait produire des résultats totalement différents lorsqu'elle est utilisée dans vos sources ou même dépendre de choses comme l'optimisation de l'assemblage ou d'autres utilisations de registre. S'il est encapsulé dans une fonction, il peut même ne pas produire le même résultat dans ces bits sur deux appels consécutifs avec les mêmes arguments.

Si l'on considère uniquement les valeurs non négatives , l'effet du décalage vers la gauche de 1 ( expression << 1 ) équivaut à multiplier l'expression par 2 (l'expression fournie * 2 ne déborde pas) et l'effet du décalage droit par 1 ( expression >> 1 ) équivaut à diviser par 2.





bit-manipulation