IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Opérateurs de bits


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Par défaut Opérateurs de bits
    Bonjour tout le monde,

    Alors voilà, j'avance tranquillement dans K&R2, mais je viens d'arriver à un bout que je ne comprends pas très bien, car il est expliqué plutôt vaguement et sans exemple [compréhensible]...

    Honnêtement, j'ai beau vouloir, je dois vraiment me casser la tête pour comprendre. Je ne suis pas si perdu je sais par exemple que :

    0011 & 0011 = 0011;
    0011 | 0010 = 0011;
    0101 ^ 0110 = 0011;
    ~0000 = 1111;

    Mais ce sont les opérateurs « << » et « >> », ainsi que la notion de masque, qui me posent problème. Merci d'avance!

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Mais ce sont les opérateurs « << » et « >> »
    Ils servent juste à décaler les bits, soit à gauche, soit à droite, de 'n' rangs.

    En supposant que "unsigned char" fasse 8 bits :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    unsigned char valeur = 26;  /* 00011010 en binaire */
    valeur = valeur << 3 ; /* décalage de 3 bits vers la gauche */
    Comme on décale 00011010 de 3 bits à gauche, on se retrouve avec 11010000, soit 208 en décimal.
    S'il y a dépassement, les bits qui débordent sont perdus.

    Exemple : Si on décale 00011010 de 4 bits à gauche, on se retrouve avec 10100000, soit 160 en décimal.

    ainsi que la notion de masque
    Un masque sert à isoler, dans un nombre, un ou plusieurs bits en particulier. Il peut être parfois utile de stocker dans une même variable plusieurs informations (sous forme de groupes de bits), dont la taille totale est égal (ou inférieure) à la taille de cette variable.

    Exemple, si tu as une variable de 8 bits :
    bits 7 (bit 7 étant tout à gauche) : information 1 (sur 1 bits)
    bit 6 : information 2 (sur 1 bit)
    bits 3,4 et 5 : information 3 (sur 3 bits)
    bits 1 et 2 : information 4 (sur 2 bits)
    bit 0 (bit 0 étant tout à droite) : information 5 (sur 1 bit).

    Donc, si tu veux lire l'information 3, tu vas devoir isoler les bits 3, 4 et 5 en appliquant un masque sur la valeur, c'est-à-dire concrètement en faisant un ET binaire avec la valeur 00011100, afin de mettre à 0 les autres bits. Ensuite, il suffit de décaler de 2 rangs le résultat vers la droite pour lire cette information. Il faudra bien entendu auparavant copier la valeur de la variable dans une variable temporaire et effectuer les opérations binaires sur elle, sinon les informations originales seront perdues.
    Si tu veux modifier la valeur de cette information pour la stocker ensuite dans la variable d'origine, il faut donc ensuite faire l'opération inverse : mettre les bits 3, 4 et 5 de ta variable à 0 , puis décaler les bits de ta variable temporaire (qui contient l'information modifiée) de 2 rangs vers la gauche, puis appliquer un OU (opérateur "|" ) sur la variable avec ta variable temporaire.

    Parfois, tu pourrais juste vouloir savoir si le bit "n" est à 1 ou non (sans tout décaler). Dans ce cas, il y a seulement un ET binaire à effectuer puis vérifier si le résultat de cette opération donne 0 ou non. Si le résultat est 0, donc le bit en question est à 0. Si le résultat est différent de 0, le bit est à 1.

    On peut effectuer tout ceci à la main (ET binaire et décalage de bits) ou via un champs de bits (une structure contenant des membres qui sont chacun composés d'un nombre déterminé de bits).

    Par contre, il faut faire attention à la portabilité.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Exemple, si tu as une variable de 8 bits :
    bits 7 (bit 7 étant tout à gauche) : information 1 (sur 1 bits)
    bit 6 : information 2 (sur 1 bit)
    bits 3,4 et 5 : information 3 (sur 3 bits)
    bits 1 et 2 : information 4 (sur 2 bits)
    bit 0 (bit 0 étant tout à droite) : information 5 (sur 1 bit).

    Donc, si tu veux lire l'information 3, tu vas devoir isoler les bits 3, 4 et 5 en appliquant un masque sur la valeur, c'est-à-dire concrètement en faisant un ET binaire avec la valeur 00011100, afin de mettre à 0 les autres bits. Ensuite, il suffit de décaler de 2 rangs le résultat vers la droite pour lire cette information. Il faudra bien entendu auparavant copier la valeur de la variable dans une variable temporaire et effectuer les opérations binaires sur elle, sinon les informations originales seront perdues.
    Si je comprends bien, si ma variable avait la valeur fictive de 10110100, et que je cherchais la valeur de l'information 3, l'opération se ferait comme suit:

    10110100 & 00011100 = 00010100,
    00010100 >> 2 = 00000101.

    et si je voulais modifier la valeur de l'information 3 pour mettre 111 à la place 101, je ferais :

    10110100 & 11100011 = 10100011,
    00000111 << 2 = 00011100,
    10100011 | 00011100 = 10111111

    Si c'est le cas, alors merci beaucoup de ton aide, ça va me permettre d'avancer dans ma lecture de K&R2.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Citation Envoyé par mrTerribleLie Voir le message
    Si je comprends bien, si ma variable avait la valeur fictive de 10110100, et que je cherchais la valeur de l'information 3, l'opération se ferait comme suit:

    10110100 & 00011100 = 00010100,
    00010100 >> 2 = 00000101.
    Attention à l'ordre des bits. Le bit 0, c'est celui le plus à droite :
    Ce serait donc plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    unsigned int masque, variable;
    unsigned int information3;
     
    variable = 180; /* 10110100 (binaire) */
    masque = 56; /* 00111000 (binaire) */
    information3 = (variable & masque) >> 3;
    et si je voulais modifier la valeur de l'information 3 pour mettre 111 à la place 101, je ferais :

    10110100 & 11100011 = 10100011,
    00000111 << 2 = 00011100,
    10100011 | 00011100 = 10111111
    Je dirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    unsigned int masque, variable;
    unsigned int information3; /* la valeur ne doit pas dépasser 3 bits */
     
    variable = 0;
     
    ...
     
    masque = 56; /* 00111000 (binaire) */
    information3 = ...; /* ce qu'on veut... */
     
    variable = (variable & ~masque) | (information3 << 3);
    Plus généralement, pour mettre le bit 'n' de 'variable' à 1, on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    variable = variable | 1 << n;
    ... et pour le mettre à 0 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    variable = variable & ~(1 << n);
    On peut aussi utiliser des macro "qui vont bien" pour alléger le code. C'est d'ailleurs ce qui est fait habituellement.

    Et on peut aussi gérer les groupes de bits avec les "champs de bits", mais ce n'est pas portable ; il faut donc faire attention. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #include <stdio.h>
     
    typedef union CHAMPS_BITS
    {
    	struct
    	{
    		unsigned char var5 : 1;
    		unsigned char var4 : 2;
    		unsigned char var3 : 3;
    		unsigned char var2 : 1;
    		unsigned char var1 : 1;
    	};
    	unsigned char var;
     
    } CHAMPS_BITS;
     
    void affiche_binaire(unsigned int valeur , int taille)
    {
    	unsigned int masque;
    	masque = 1 << (taille - 1);
     
    	printf("binaire : ");
    	while (masque)
    	{
    		printf("%c" , ((valeur & masque) ? '1' : '0'));
    		masque >>= 1;
    	}
    	printf("\n");
    }
     
    int main (void)
    {
    	CHAMPS_BITS champs_bits;
    	int i;
     
    	champs_bits.var = 0;
     
    	for (i = 0 ; i <= 7 ; i++)
    	{
    		champs_bits.var3 = i;
    		printf("Mise a %d de 'var3' : \n" , i);
    		affiche_binaire(champs_bits.var , sizeof(champs_bits.var) * 8);
    		printf("\n");
    	}
     
    	getchar();
     
    	return 0;
    }

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Par défaut
    En fait le problème, c'est que je n'ai pas commencé par zéro... donc c'est pour cela que je me trouve à faire ">> 2" plutôt que ">> 3", une simple petite erreur d'inattention....

    Merci quand même, ton premier post m'a aidé à comprendre ce qui me semblait incompréhensible

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Binaire] Opérateurs de rotation dee bits ?
    Par Tifauv' dans le forum C
    Réponses: 3
    Dernier message: 09/11/2017, 11h29
  2. Gestion des droits, opérateurs de bits
    Par gwharl dans le forum Langage
    Réponses: 2
    Dernier message: 19/07/2011, 13h10
  3. Opérateurs de bits et indexes ?
    Par sunseb7 dans le forum MySQL
    Réponses: 1
    Dernier message: 23/02/2010, 17h58
  4. opérateur de bits sur type signé
    Par gronaze dans le forum C
    Réponses: 6
    Dernier message: 18/09/2009, 19h05
  5. [Tableaux] Problème d'opérateurs de bits
    Par tonypeter dans le forum Langage
    Réponses: 2
    Dernier message: 04/03/2007, 16h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo