10
votes

Échanger une paire de bits dans un octet

J'ai un article arbitraire Binaire 8 bits 8 bits E.G., 11101101

Je dois échanger toutes les paires de bits comme:

Avant d'échanger: 11-10-11-01 Après échange: 11-01-11-10

On m'a demandé cela dans une interview!


2 commentaires

Désolé pour la première réponse que j'ai donnée si cela vous a confondu. Je lis complètement votre avant / après tort.


@Jamesm: Désolé, si ce n'est pas évident, mais la question est la suivante: dans un octet, paire des bits pour, par exemple, si l'octet est 10101100, jumelez les bits à ressembler - 10 - 10 - 11 - 00 . Maintenant, si nous échangeons les paires individuelles, cela deviendrait - 01 - 01 - 11 - 00 . J'avais besoin du mécanisme pour mettre en œuvre l'échange


6 Réponses :


0
votes
b = (a & 170 >> 1) | (a & 85 << 1)

2 commentaires

C'est totalement illisible; De plus, il est inefficace et même incorrect pour les cas de bord. La division par deux n'est pas équivalente à un changement de droite un peu pour les nombres négatifs.


Identique que les TDammers répondent, mais c'est plus propre et explicitement binaire, pendant que vous utilisez des nombres décimaux.



-6
votes

Je voudrais d'abord coder cela «Longhand» - c'est-à-dire de plusieurs étapes évidentes et explicites, et utilisez-la pour valider que les tests d'unité que j'avais mis en place fonctionnaient correctement, puis ne vous déplacez que dans plus de solutions de manipulation de bits ésotériques. Si j'avais besoin de performance (et que des performances supplémentaires ont été livrées par ces améliorations)

code pour les personnes d'abord, Ordinateurs de seconde.


0 commentaires

33
votes

en pseudo-code: xxx

Il fonctionne en manipulant les bits faibles et les bits élevés de chaque paire de bits séparément, puis combinant le résultat:

  • L'expression x & 0b10101010 extrait le bit haut de chaque paire, puis >> 1 le décalage vers la position basse bit.
  • De même, l'expression (x & 0b01010101) << 1 extrait le bit bas de chaque paire et la déplace vers la position de bits élevée.
  • Les deux parties sont ensuite combinées à l'aide de Bitwise-ou.

    Étant donné que toutes les langues ne vous permettent pas d'écrire directement des littéraux binaires, vous pouvez les écrire par exemple hexadecimal: xxx


3 commentaires

Étant donné que toutes les langues ne respectent pas le modèle 0b ..., il convient probablement de noter que c'est 0xaa et 0x55 dans Hex respectivement.


@userx: +1 Oui, c'est certainement la peine de noter. Ajoutée.


Merci Mark. C'est une méthode géniale!



6
votes
  1. Faites des masques de deux bits, un contenant tous les morceaux même et une contenant les bits inégaux ( 10101010 et 01010101 ).
  2. Utilisez le bitwise-et pour filtrer l'entrée en deux nombres, l'un ayant tous les morceaux même à zéro, l'autre ayant tous les bits inégaux à zéro.
  3. Décaler le numéro qui ne contient que même des bits un bit à gauche et l'autre un un peu à droite
  4. Utilisez Bitwise-ou pour les combiner ensemble.

    Exemple pour 16 bits (pas code réel): xxx


2 commentaires

Euh .. je pense que vous voulez dire 0xaa au lieu de 0x10101010 (0xaa étant 10101010 en binaire) et 0x55 au lieu de 0x01010101. Bien pour un octet quand même. 0xaaaa et 0x5555 respectivement pour un court-circuit.


Ouais, déjà édité le pseudocode de type C à utiliser binaire à la place. La question originale indique de toute façon 8 bits, alors ...



0
votes
Comme d'autres l'ont dit,

La solution la plus élégante et la plus flexible est que d'autres, d'appliquer un masque «peigne» aux bits paires et aux bits impairs séparément, puis les ont déplacés à gauche et à droite un endroit pour les combiner à l'aide de Bitwise ou.

Une autre solution que vous voudrez peut-être penser à tirer parti de la taille relativement petite de votre type de données. Vous pouvez créer une table de recherche de 256 valeurs initialement initialisée aux valeurs que vous souhaitez comme sortie à votre entrée: xxx

Chaque valeur est placée dans la matrice pour représenter le tableau pour représenter transformation de l'index. Donc si vous faites cela: xxx

out contiendra 0x55

C'est plus Cumbersomeome et moins flexible que la première approche (que si vous voulez passer de 8 bits à 16?) Mais cela a-t-il l'approche qu'il sera plus rapide si l'exécution d'un grand nombre de ces opérations.


0 commentaires

0
votes

Supposons que votre numéro soit num .

Trouvez d'abord le bit de la position même:
num & oxaaaaaaaa

deuxième étape Trouver la position impaire:

num & ox55555555

3ème étape Changement de position Position d'une position impaire à un peu de position et même de position à un peu de position impairs:
Même = (Num & Oxaaaaaaaaa) >> 1
impair = (num & 0x55555555) << 1

dernière étape ... résultat = même | Impair

Résultat d'impression


0 commentaires