8
votes

Quels sont les représentants 0x01 et 0x80 des opérations bitwises en C?

J'essaie d'inverser l'ordre des bits en C (Question des devoirs, Objet: Opérateurs Bitwise). J'ai trouvé Cette solution , mais je suis un peu confus par les valeurs hexagonales utilisées - 0x01 et 0x80.

  unsigned char reverse(unsigned char c) {
     int shift;
     unsigned char result = 0;

     for (shift = 0; shift < CHAR_BITS; shift++) {
        if (c & (0x01 << shift))
            result |= (0x80 >> shift);
     }
     return result;
  }


1 commentaires

Une bizarrerie dans le code ... char_bits n'est pas la définition standard - c'est char_bit , défini dans .


4 Réponses :


8
votes

0x01 est le mit de bit le moins important, par conséquent, la valeur décimale est 1.

0x80 est le bit le plus significatif d'un ensemble d'octets 8 bits. S'il est stocké dans un caractère signé (sur une machine utilisant la notation de 2's-complément - comme la plupart des machines que vous êtes susceptibles de rencontrer la volonté), c'est la valeur la plus négative (décimale -128); Dans un caractère non signé, il est décimal +128. P>

L'autre motif qui devient la deuxième nature est 0xFF avec tous les bits; C'est décimal -1 pour les caractères signés et 255 pour des caractères non signés. Et, bien sûr, il y a 0x00 ou zéro sans bits. P>

Quelle est la boucle du premier cycle pour vérifier si le LSB (bit le moins significatif) est défini et s'il est, définit le MSB (le plus significatif) dans le résultat. Au prochain cycle, il vérifie le prochain LSB et définit la suivante de MSB, etc. P>

| MSB |     |     |     |     |     |     | LSB |
|  1  |  0  |  1  |  1  |  0  |  0  |  1  |  1  |   Input
|  1  |  1  |  0  |  0  |  1  |  1  |  0  |  1  |   Output
|  1  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |   0x80
|  0  |  0  |  0  |  0  |  0  |  0  |  0  |  1  |   0x01
|  0  |  1  |  0  |  0  |  0  |  0  |  0  |  0  |   (0x80 >> 1)
|  0  |  0  |  0  |  0  |  0  |  0  |  1  |  0  |   (0x01 << 1)


4 commentaires

Prudent. Les valeurs négatives ne sont valables que pour la représentation des entiers de deux compléments. Dans un complément ou la signature, les motifs de bits ont des significations différentes. C ne nécessite pas l'utilisation de TWO-Complément.


@Steve: assez vrai ... j'ai ajusté la réponse en conséquence.


Wow. Merci pour l'explication - L'illustration est vraiment bloquée pour moi.


Grande explication!



0
votes

0x01 signifie 1-a un dans ceux de la place et 0x80 signifie 128-an 8 dans la place des Sixteens. Ces chiffres font référence au bit le plus bas et au bit le plus élevé d'un nombre huit bits, respectivement. Les déplacer donne des masques pour les bits individuels de l'octet.

EDIT: dans un nombre hexadécimal, les chiffres vont en puissance de seize ans, pas de pouvoirs de dix. Donc, le premier chiffre à partir de la droite est celui de la place (0x1 = 1), le deuxième chiffre est la place des Sixteens (0x10 = 16), le troisième chiffre est la deuxième place de deux cent cinquante-six (0x100 = 256), et Donc sur.


2 commentaires

Sixteens Place? Voulez-vous résoudre ce problème ou expliquer cela?


Si vous regardez chaque nybble comme un chiffre dans la représentation de la base-16 du nombre, alors 8 est dans la place des Sixteens. Mais je doute que cela soulagera la confusion des OPS.



5
votes

Chaque chiffre hexagonal représente 4bits, donc

  • 0x01 est juste une longue façon d'écrire 1.
  • 0x80 est une courte façon d'écrire en binaire [1000] [0000], ou 128.

    La solution utilise des opérateurs binaire pour tester et définir des valeurs.

    L'expression: xxx

    Exécute "..." Si le même bit est 1 dans "A" dans "A" et "B".

    L'expression xxx

    définit les bits dans "C" à 1, S'ils sont 1 dans 'B'.

    La boucle déplace le test et le jeu de jeu de la ligne.

    bonne chance!


0 commentaires

1
votes

Les valeurs 0x01 et 0x80 sont délibérément écrites en notation hexadécimale pour souligner leur signification comme les bits les moins importants et les plus importants du type non signé Char < /code >.puce actuelle, l'auteur a fait plusieurs erreurs:

  • Le macro char_bits est mal orthographié: il devrait être char_bit .
  • en utilisant char_bit au lieu de codage rigide La valeur presque universelle 8 est un effort précieux pour une portabilité complète, mais cet effort est annulé par l'utilisation de 0x80 qui n'est valide que si char_bit == 8 .
  • Il y a un autre problème de portabilité subtil: 0x01 << Changer aurait un comportement non défini pour shift = char_bit-1 sur une plate-forme où taille de taille == taille de (int) parce que 0x01 a type int (et pas non signé INT , contre-intuitif n'est-ce pas?) .

    Voici une version corrigée qui fonctionne sur toutes les plates-formes confidentielles: xxx


0 commentaires