Dans une interview, on m'a demandé d'échanger les 4 premiers 4 bits d'un numéro avec le dernier 4 bit. (par exemple, 1011 1110 devrait être 1110 1011.) P>
Quelqu'un a-t-il une solution pour cela? P>
15 Réponses :
Utilisez simplement une variable temporaire et déplacez le dernier bit dans cette variable, puis déplacez le bit dans cette direction et la fin du masquage dans les bits du VaR TMP et vous avez terminé.
Mise à jour : strong>
Ajoutons du code, puis vous pouvez choisir ce qui est plus lisible. P> la doublure de fonctionnement d'un p> le même code mais avec un peu TMP Vars P>
unsigned int data = 0x7654;
unsigned int tmp1 = 0;
unsigned int tmp2 = 0;
tmp1 = (0x0f&data)<<4;
tmp2 = (0xf0&data)>>4;
tmp1 = tmp1 | tmp2;
data = data ^ (data & 0xff);
data = data | tmp1;
printf("data %x \n", data);
Pas besoin d'une variable temporaire là-bas, il peut tous être fait dans une expression.
Pourquoi cette fascination de tout faire dans une expression? L'utilisation d'une variable temporaire est simple, lisible et fonctionne.
Le Var TMP le rend généralement plus lisible et quand il devient un peu plus compliqué ....
La doublure est assez simple et lisible.
Mais appuyez sur le code dans GDB et voyez à quel point il est facile de déboguer d'une doublure ... Un doublure est agréable quand ils travaillent :)
@Johan: Facile, faire un Si code> (instruction étape) au lieu d'un
étape code> et regardez le registre EAX (ou RAX) à l'aide de
Affichage / x $ eax code>.
J'avais supposé que Intel CPU, mais vous pouvez toujours utiliser si code> sur d'autres processeurs et regarder d'autres registres tout aussi facilement.
Cela ne échange pas les 4 premiers avec les 4 derniers, il échange le premier (ou dernier, selon lequel vous êtes confrontés) avec les 4 suivants.
Il n'y a pas besoin d'une variable temporaire, comme cela devrait le faire:
x = ((x & 0xf) << 4) | ((x & 0xf0) >> 4);
Tournez à gauche ... (voir Commentaire à Ken Keenan)
Comme certains des autres commentaires suggèrent, le ci-dessus ne fonctionne que sur une variable d'octets de 8 bits x.
@Ktc: presque mais pas tout à fait, vous êtes sur la bonne voie cependant.
Ce qui est à propos de Greg, c'est que cela ne fonctionne pas nécessairement si X est signé et a une valeur négative, puisque le décalage correct peut alors être arithmétique au lieu de logique.
Accrochez-vous, je le reprends. Le masque avec 0xf0 favorise à INT si INT est d'au moins 17 bits, ou non signé INT si INT n'est que de 16 bits. Quoi qu'il en soit, le décalage sera alors logique, car soit le bit de signe de x est supprimé par le masque, sinon la valeur décalée est de type non signé.
unsigned char c; c = ((c & 0xf0) >> 4) | ((c & 0x0f) << 4);
(Voir commentaire à Greg Hewgill) ... Tourner à droite.
Comme certains autres commentaires suggèrent, ce qui précède ne fonctionne que sur un caractère 8 bits. (C garantie / définir le caractère d'un octet, qui doit être au moins 8 bits, mais peut être plus.)
cherchez-vous quelque chose de plus intelligent que le changement de bit standard?
(supposer A est un type 8 bits) p>
C ++ - comme pseudocode (peut être facilement réécrit pour ne pas utiliser de variables temporaires): Cela nécessitera que Char_bit soit défini. Il est généralement dans la limite.h et est défini comme 8 bits, mais elle dépend strictement de la plate-forme et ne peut pas être définie du tout dans les en-têtes. P> P>
Um,
Assemblée X86:
asm{ mov AL, 10111110b rol AL rol AL rol AL rol AL }
J'aime ce "hors de la boîte" -Entant de sortir de la question et de fournir une réponse qui ne répond pas vraiment à la question, mais fournit probablement une solution précieuse. Néanmoins, ce faisant, il faut laisser des informations supplémentaires, comme "Cela n'est pas sage si vous envisagez d'écrire C code qui compile sur différentes familles de processeur" ou "et que vous devez l'encapsuler dans la déclaration suivante pour que cela puisse devenir c" . Sinon, répondre à une question C avec assembleur n'est pas exactement correcte.
Vous avez raison, le vote au bas est bien mérité
Sauf si vous vous souciez de l'original 8086 (la rotation immédiate-comptage a été nouvelle en 186, IIRC), utilisez rol al, 4 code>.
Si vous n'avez pas vu ni fait beaucoup de twiddling, une bonne ressource à étudier est la suivante: p>
Battez-moi-moi, j'allais suggérer la même chose. :)
Mes compétences dans ce domaine sont nouvelles et non prouvées, donc si je me trompe, j'apprends quelque chose de nouveau, qui fait au moins une partie du débordement de la pile.
Un bitmask et XOR fonctionnent également?
comme? p>
var orginal= var mask =00001110 //I may have the mask wrong var value=1011 1110 var result=value^mask;
Non, cela ne fonctionnerait pas, car le swap doit déplacer des morceaux et les opérations bitwises doivent traiter chaque bit de manière indépendante de tous les autres. (C'est pourquoi ils s'appellent "Bitwise") Toutefois, c'est un malentendu courant, en particulier parce que le terme "bits d'échange" est parfois utilisé pour signifier "bits d'inversion" - que XOR a raison.
Il n'y a pas de "réponse correcte" à ce type de question d'entretien. Il y a plusieurs façons de faire cela (tables de recherche, quiconque?) Et les compromis entre chaque passage (lisibilité contre la performance contre la portabilité contre la maintenabilité) devraient être discutés. p>
La question est juste un gambit d'ouverture pour vous faire discuter de certaines des questions ci-dessus et de déterminer la manière dont vous pouvez discuter de tels problèmes. p>
Je ne pense pas que "ce type de question d'entretien" concerne une solution correcte, mais sur la manière dont vous approchez et résolvez le problème. Une partie de votre classement pourrait même être que vous avez posé les bonnes questions avant de résoudre le problème.
unsigned char b; b = (b << 4) | (b >> 4);
Le plus facile est (T est non signé): mais si vous souhaitez obfosser votre code, ou pour échanger une combinaison d'autres bits, vous pouvez utiliser cette base: p> mask = 0x0F & (t ^ (t >> 4));
t ^= (mask | (mask << 4));
#include <stdio.h> #include <conio.h> #include <math.h> void main() { int q,t,n,a[20],j,temp; int i=0; int s=0; int tp=0; clrscr(); printf("\nenter the num\n"); scanf("%d",&n); t=n; while(n>0) { a[i]=n%2; i++; n=n/2; } printf("\n\n"); printf("num:%d\n",t); printf("number in binary format:"); for(j=i-1;j>=0;j--) { printf("%d",a[j]); } printf("\n"); temp=a[i-1]; a[i-1]=a[0]; a[0]=temp; printf("number in binary format wid reversed boundary bits:"); for(j=i-1;j>=0;j--) { printf("%d",a[j]); } printf("\n"); q=i-1; while(q>=0) { tp=pow(2,q); s=s+(tp*a[q]); q--; } printf("resulatnt number after reversing boundary bits:%d",s); printf("\n"); getch(); }
Ce programme échangera d'abord et le dernier bit de n'importe quel nombre sans utiliser d'opérateur logique.
Normalement, vous mettez le texte d'explication dans votre réponse et non comme un commentaire sur la réponse.
/*swaping four bits*/ #include<stdio.h> void printb(char a) { int i; for( i = 7; i >= 0; i--) printf("%d", (1 & (a >> i))); printf("\n"); } int swap4b(char a) { return ( ((a & 0xf0) >> 4) | ((a & 0x0f) << 4) ); } int main() { char a = 10; printb(a); a = swap4b(a); printb(a); return 0; }
Voici comment vous échangez des bits entièrement, pour changer l'endanianesse du bit dans un octet.
"iin" est en fait un entier parce que je l'utilise pour lire à partir d'un fichier. J'ai besoin des bits dans une commande où je peux facilement les lire dans l'ordre. P> pour échanger seulement deux moustiquaires dans un seul octet, c'est le moyen le plus efficace de le faire. , et il est probablement plus rapide qu'une table de recherche dans la plupart des situations. P> Je vois beaucoup de gens faire changer et oublier de faire le masquage ici. Ceci est un problème quand il y a une extension de signe. Si vous avez le type de caractère non signé, c'est bien que c'est une quantité non signée 8 bits, mais elle échouera avec un autre type. P> Le masque n'ajoute pas de frais généraux, avec un caractère non signé, le masque est implicite de toute façon et tout compilateur décent supprimera un code inutile et a pendant 20 ans. P> P>
solution pour les n bits génériques échange entre le dernier et le premier.
Non vérifié pour le cas lorsque les bits totaux sont inférieurs à 2n.
ici 7 est pour char, prendre 31 pour entier.
bit_print (U2); n'est pas défini