2009-06-16 6 views
1

J'ai un vieux code comme ceci:décalage de bits confusion en C#

private int ParseByte(byte theByte) 
{ 
     byte[] bytes = new byte[1]; 
     bytes[0] = theByte; 
     BitArray bits = new BitArray(bytes); 

     if (bits[0]) 
      return 1; 
     else 
      return 0; 
} 

Il est long et je me suis dit que je pourrais le couper comme ceci:

private int ParseByte(byte theByte) 
{ 
     return theByte >> 7; 
} 

Mais, je ne reçois pas les mêmes valeurs que la première fonction. L'octet contient 00000000 ou 10000000. Que manque-t-il ici? Est-ce que j'utilise un opérateur incorrect?

Répondre

4

Le problème est que, dans la première fonction, les bits [0] retournent le bit le moins significatif, mais la seconde renvoie le bit le plus significatif. Pour modifier la deuxième fonction pour obtenir le bit le moins significatif:

private int ParseByte(byte theByte) 
{ 
    return theByte & 00000001; 
} 

Pour modifier la première fonction de retourner le bit le plus significatif, vous devez utiliser les bits [7] - pas de bits [0].

+0

ainsi, l'éditeur hexadécimal que j'ai utilisé pour regarder les données l'ont affiché comme 10000000. Je suppose qu'il a affiché le LSB en premier? et j'ai eu de la chance avec ma confusion dans le BitArray? – scottm

+0

@ scott2012: Je ne peux pas parler pour votre éditeur hexadécimal, mais comment fonctionne BitArray - le bit le moins significatif est à l'index 0. Vous pouvez vérifier cela avec un court morceau de code: bits var = new BitArray (nouvel octet [] {0xf0}); // 11110000 pour (int idx = 0; idx <= 7; idx ++) Console.WriteLine ("{0}: {1}", idx, bits [idx]); –

0

Peut-être que la première fonction devrait vérifier les bits [7]?

+0

La première fonction obtient ce que je veux, la seconde ne fonctionne pas. – scottm

+0

fait le travail suivant: return ((int) theByte == 128)? dix ; –

0

Vous avez un zéro supplémentaire dans vos nombres binaires (vous avez 9 chiffres chacun). Je suppose que c'est juste une faute de frappe.

Êtes-vous sûr de bien commander votre commande? Le binaire est traditionnellement écrit de droite à gauche, pas de gauche à droite comme la plupart des autres systèmes de numérotation. Si le numéro binaire que vous avez affiché est formaté en propriété (ce qui signifie que 10000000 est vraiment le numéro 128 et non le numéro 1) alors votre premier extrait de code ne devrait pas fonctionner et le second devrait l'être. Si vous l'écrivez en arrière (ce qui signifie 10000000 est 1, pas 128), alors vous n'avez même pas besoin de bitshift. Juste ET avec 1 (theByte & 1). En fait, quelle que soit l'approche, un AND binaire (opérateur &) semble plus approprié. Étant donné que votre première fonction fonctionne et la seconde ne fonctionne pas, je suppose que vous venez d'écrire le numéro à l'envers et que vous avez besoin de le faire avec 1 comme décrit ci-dessus.

+0

a corrigé la faute de frappe. Je ne l'écris pas en arrière, c'est un format pour certaines données binaires que je suis en train de lire. Je ne sais pas pourquoi cela a été fait de cette façon. Je vais essayer et si – scottm

0

Selon un utilisateur sur Microsoft's site le BitArray stocke en interne les bits dans Int32s en big endian dans l'ordre des bits. Cela pourrait causer le problème. Pour une solution et d'autres informations, vous pouvez visiter le lien.

3

La fonction équivalente à la première snipet est:

return theByte & 1 == 1 

Dans la deuxième snipet vous chechink le bit le plus significatif et le premier snipet le moins significatif.

0

1st La première fonction ne fonctionne pas car elle essaie de renvoyer une chaîne à la place d'un int.

Mais ce que vous voudrez peut-être est la suivante:

private static int ParseByte(byte theByte) 
    { 
     return theByte & 1; 
    } 

Cependant, vous pouvez également ceci:

private static string ParseByteB(byte theByte) 
    { 
     return (theByte & 1).ToString(); 
    } 
+0

Correction de la faute de frappe – scottm

1

Voulez-vous revenir int ou une chaîne? Quoi qu'il en soit - vous pouvez utiliser modulo:

return theByte % 2 == 0 ? "0" : "1" 

OK, vous avez modifié ...et voulez retourner int

Un mot à votre opération de changement de vitesse: vous devez utiliser < < au lieu de >>. Mais cela revient (lorsque vous lancez à l'octet au lieu de int) 0 ou 128 et non 0 ou 1. Vous pouvez réécrire votre deuxième solution comme:

return (byte)(theByte << 7) == 128 ? 1 : 0; 

Mais les autres réponses contiennent des solutions vraiment mieux que cela.