117 votes

Obtenir un bit spécifique d'un octet

J'ai un octet, plus précisément un octet d'un tableau d'octets qui est arrivé par UDP depuis un autre appareil. Cet octet stocke l'état on/off de 8 relais dans le dispositif.

Comment obtenir la valeur d'un bit spécifique dans un octet ? Idéalement, une méthode d'extension serait la plus élégante et le retour d'un bool serait le plus logique pour moi.

public static bool GetBit(this byte b, int bitNumber)
{
    //black magic goes here
}

206voto

KeithS Points 36130

Facile. Utilisez un AND au sens du bit pour comparer votre nombre avec la valeur 2^bitNumber, qui peut être calculée à peu de frais en décalant des bits.

//your black magic
var bit = (b & (1 << bitNumber-1)) != 0;

EDIT : Pour ajouter un peu plus de détails car il y a beaucoup de réponses similaires sans explication :

Un ET binaire compare chaque nombre, bit par bit, à l'aide d'une jointure ET pour produire un nombre qui est la combinaison de bits où le premier bit et le deuxième bit à cet endroit ont tous deux été activés. Voici la matrice logique de la logique ET dans un "nibble" qui montre le fonctionnement d'un ET bit à bit :

  0101
& 0011
  ----
  0001 //Only the last bit is set, because only the last bit of both summands were set

Dans votre cas, nous comparons le nombre que vous avez passé avec un nombre qui n'a que le bit que vous voulez rechercher. Disons que vous cherchez le quatrième bit :

  11010010
& 00001000
  --------
  00000000 //== 0, so the bit is not set

  11011010
& 00001000
  --------
  00001000 //!= 0, so the bit is set

Le décalage de bits, pour produire le nombre auquel nous voulons comparer, est exactement ce qu'il semble être : prendre le nombre, représenté comme un ensemble de bits, et décaler ces bits vers la gauche ou la droite d'un certain nombre de positions. Étant donné qu'il s'agit de nombres binaires et que chaque bit est une puissance de deux supérieure à celle du bit à sa droite, le décalage des bits vers la gauche équivaut à doubler le nombre une fois pour chaque place décalée, ce qui revient à multiplier le nombre par 2^x. Dans votre exemple, en cherchant le quatrième bit, on effectue :

       1 (2^0) << (4-1) ==        8 (2^3)
00000001       << (4-1) == 00001000

Vous savez maintenant comment cela se passe, ce qui se passe à bas niveau, et pourquoi cela fonctionne.

59voto

Ben Voigt Points 151460

Même s'il est bon de lire et de comprendre la réponse de Josh, vous serez probablement plus heureux en utilisant la classe fournie par Microsoft à cet effet : System.Collections.BitArray Il est disponible dans toutes les versions de .NET Framework.

42voto

Josh Petrie Points 4000

Ce site

public static bool GetBit(this byte b, int bitNumber) {
   return (b & (1 << bitNumber)) != 0;
}

devrait le faire, je pense.

10voto

PierrOz Points 2679

Une autre façon de faire :)

return ((b >> bitNumber) & 1) != 0;

8voto

Jay Walker Points 2215

Utilisation de Tableau de bits et en créant une méthode d'extension comme le suggère OP :

public static bool GetBit(this byte b, int bitNumber)
{
    System.Collections.BitArray ba = new BitArray(new byte[]{b});
    return ba.Get(bitNumber);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X