Échanger deux bits avec une seule opération en C?
Disons que j'ai un octet avec six valeurs inconnues:
???1?0??
et je veux swap bits 2 et 4 (sans la modification de la ?
valeurs):
???0?1??
Mais comment pourrais-je le faire dans une opération en C?
Je suis l'exécution de cette opération des milliers de fois par seconde sur un microcontrôleur de sorte que les performances est la priorité absolue.
Il serait bien de "basculer" de ces bits. Même si ce n'est pas la même que la permutation des bits, le basculement va fonctionner très bien pour mes besoins.
source d'informationauteur Nate Murray | 2009-06-11
Vous devez vous connecter pour publier un commentaire.
Essayer:
Qui fait basculer les deux bits. C'est un peu de clarté dans la question que vous première mention de swap et de donner ensuite une bascule exemple. De toute façon, pour échanger les bits:
où precomputed_lookup est une 256 tableau d'octets, pourrait être le moyen le plus rapide, il dépend de la vitesse de la mémoire par rapport à la vitesse du processeur. Sinon, c'est:
EDIT: plus d'informations sur le basculement de bits.
Lorsque vous xor (
^
) de deux valeurs entières ensemble, le xor est effectuée au niveau du bit, comme ceci:de sorte que le bit 0 de la première valeur est xor ed avec le bit 0 de la deuxième valeur, bit 1 avec le bit 1 et ainsi de suite. L'opération xor de ne pas modifier les autres bits de la valeur. En effet, c'est un parallèle bits xor sur plusieurs bits.
En regardant la table de vérité pour le xor, vous verrez qu'utilise xor un peu avec la valeur "1", effectivement bascule de l'bits.
Donc, pour basculer entre les bits 1 et 3, écrire un nombre binaire avec un où vous souhaitez que le bit à bascule et un zéro si vous voulez laisser la valeur inchangée:
convertir à l'hex: 0x0a. Vous pouvez passer autant de bits que vous le souhaitez:
basculer les bits 0, 3, 4 et 5
Vous ne pouvez pas "swap" deux bits (c'est à dire les bits de changer de place, pas de valeur) en une seule instruction à l'aide des bits de violon.
L'approche optimale si vous voulez vraiment swap est probablement une table de recherche. Cela est vrai pour de nombreux 'maladroit' transformations.
La méthode suivante n'est PAS un seul C l'enseignement, c'est juste un peu tripoter la méthode. La méthode a été simplifié à partir de Permutation des bits individuels avec XOR.
Comme indiqué dans Roddy réponseune table de recherche serait le mieux. Je ne suggèrent ce au cas où vous ne souhaitez pas utiliser un. Ce sera en effet swap de bits également, et pas seulement de la bascule (qui est, tout ce qui est dans le bit 2 à 4, et vice-versa).
r: le résultat
x = ((b >> 2) ^ (b >> 4)) & 0x01
r = b ^ ((x << 2) | (x << 4))
Explication rapide: obtenir les deux bits que vous souhaitez regarder et XOR, stocker la valeur de
x
. En reportant cette valeur de retour de bits 2 et 4 (et OU pratiquent ensemble), vous obtenez un masque que lorsque XORed de retour avecb
permettra d'échanger vos deux d'origine bits. Le tableau ci-dessous montre tous les cas possibles.Je n'ai pas tester pleinement le présent, mais pour les quelques cas que j'ai essayé rapidement, il semblait fonctionner.
Cela pourrait ne pas être optimisé, mais il devrait fonctionner:
La fonction ci-dessous échange les bits 2 et 4. Vous pouvez l'utiliser pour précalculer une table de recherche, si nécessaire (de sorte que la permutation devient une seule opération):
J'ai écrit chaque opération sur une ligne distincte pour la rendre plus claire.
Dire que votre valeur est x je.e, x=???1?0??
Les deux bits peut être activé ou désactivé par cette opération:
n
est le nombre entier vous voulez être échangé,a
etb
sont les positions (index) des bits que vous souhaitez être échangés, à compter de la moins de bits significatifs, et à partir de zéro.À l'aide de votre exemple (
n = ???1?0??
), vous pourriez appeler la fonction comme suit:Justification: il vous suffit de permuter les bits si elles sont différentes (c'est pourquoi
r != s
). Dans ce cas, l'un d'eux est 1 et l'autre est de 0. Après cela, juste un avis que vous voulez faire exactement un ensemble de bitset peu opération.