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 :

manipulation de bits


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut manipulation de bits
    Bonjour tout le monde,

    voilà, je suis en train d'implémenter une série de fonctions pour manipuler des bits. Sur l'une d'entre elle, j'ai un gros doute. Il s'agit d'une fonction qui doit modifier un bit dans un octet. Comme paramètres, elle prend un char (nous supposerons ici qu'un char fait 8 bits), un int qui correspond à la position du bit à modifier, et un bool qui est la valeur que doit prendre le bit modifié (false->0, true->1). Or je trouve la méthode que j'utilise ne me plait pas, je suis sûr qu'on peut faire beaucoup plus simple (et rapide):

    Voici ma fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // c est le char que l'on va modifier
    // pos la position du bit a modifier
    // bit la valeur du bit a modifier
    void SetBit( char & c, const int pos, const bool bit = true )
    {
       c = bit ? c|mask[pos] : ~(~c|mask[pos] );
    }
     
    // mask est un tableau de 8 char initialisé ainsi:
    char mask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
    Si ce post vous intéresse et que vous êtes motivé pour trouver, voici une fonction qui affiche un char sous forme binaire (de même, il est certainement possible de faire beaucoup plus simple que ce que j'ai fait):
    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
    // affiche un char sous forme binaire
    // par exemple, PrintBin( 0x3E ) va afficher '00111110'
    void PrintBin( const char c )
    {
       for ( int i=0; i<8; i++ )
       {
          if( (int) ( c & mask[i] ) == 0 )
          {
             cout << "0";
          }
          else
          {
             cout << "1";
          }
       }
       cout << endl;
    }
    Voilà, donc si vous avez des idées pour améliorer ce code, ou si vous voyez des erreurs, n'hésitez pas.

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    hello,
    moi j'aurais fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void SetBit( char & c, const int pos, const bool bit = true )
    {
       c = c|mask[pos];
    }
    je vois pas ce que ça fait...

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par loicounet Voir le message
    hello,
    moi j'aurais fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void SetBit( char & c, const int pos, const bool bit = true )
    {
       c = c|mask[pos];
    }
    je vois pas ce que ça fait...
    ça gère le cas où bit == false, c'est a dire qu'il faut mettre le nième bit à 0. En effet, c = c|mask[pos]; fonctionne si l'on doit mettre le bit à 1, mais ça ne foncitonne pas si on veut le mettre à 0.

    @medinoc: nickel

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Au fait: Pourquoi commences-tu par le poids fort ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Ben je sais pas. Ca reviens au même non?

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ben, c'est surtout inhabituel. Généralement, on appelle "bit 0" le bit de poids faible...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Essaie plutôt ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     c = bit ? c|mask[pos] : c&~mask[pos];
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par r0d Voir le message
    Bonjour tout le monde,
    Si ce post vous intéresse et que vous êtes motivé pour trouver, voici une fonction qui affiche un char sous forme binaire (de même, il est certainement possible de faire beaucoup plus simple que ce que j'ai fait):
    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
    // affiche un char sous forme binaire
    // par exemple, PrintBin( 0x3E ) va afficher '00111110'
    void PrintBin( const char c )
    {
       for ( int i=0; i<8; i++ )
       {
          if( (int) ( c & mask[i] ) == 0 )
          {
             cout << "0";
          }
          else
          {
             cout << "1";
          }
       }
       cout << endl;
    }
    Voilà, donc si vous avez des idées pour améliorer ce code, ou si vous voyez des erreurs, n'hésitez pas.
    En une seule ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::cout << std::bitset<std::numeric_limits<char>::digits>(my_char) << std::endl;
    Ou quelque chose comme ça (en tout cas, le code ci-dessus calcule correctement la taille en bits d'un char )

    A noter aussi les méthodes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // ça te rappelle pas quelque chose ?
    bitset<N>& bitset<N>::set(size_t pos, bool val = true);
    // histoire de récupérer la valeur après coup.
    unsigned long bitset<N>::to_ulong() const;
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  9. #9
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Ben en fait, j'ai essayé avec un bitset au début, mais le problème c'est que bitset n'a pas d'iterateur. Donc pas de begin() ni end(). Et du coup je n'ai pas réussi à l'utiliser

  10. #10
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par r0d Voir le message
    Ben en fait, j'ai essayé avec un bitset au début, mais le problème c'est que bitset n'a pas d'iterateur. Donc pas de begin() ni end(). Et du coup je n'ai pas réussi à l'utiliser
    Oui, je me suis un peu emporté... Corrigé
    Il y a une méthode size(), un opérateur [], une méthode to_string() et les opérateurs << (ostream& ..) et >> (istream& ..), donc on devrait pouvoir s'en sortir.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Waaaahhh ok ça y est j'ai compris!!


    trop pratique en fait cette classe bitset!!


  12. #12
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    J'aurais fait comme ça (c'est en C par contre, je ne connais pas le C++) :
    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
    unsigned char SetBit (unsigned char c, unsigned int pos, unsigned int bit)
    {
       unsigned int t = 1 << pos;
     
       if (bit == 0)
       {
          t = ~t;
          c = c & t;
       }
       else
       {
          c = c | t;
       }
     
       return c;
    }
    Et ça utilise les indices de bits traditionnels (ça vaut mieux, tout le monde est habitué à faire comme ça).

    Pour PrintBin() :
    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
    #include <limits.h>
    #include <stdio.h>
     
    void PrintBin (unsigned char c)
    {
       unsigned int cpt;
     
       for (cpt = 0; cpt < CHAR_BIT; ++cpt)
       {
          printf("%u", (c & (0x80 << (CHAR_BIT-8))) >> (CHAR_BIT-1) );
          c = c << 1;
       }
     
       fflush(stdout);
    }

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

Discussions similaires

  1. manipulation de bits d'un byte
    Par orelero dans le forum Langage
    Réponses: 6
    Dernier message: 22/08/2008, 10h41
  2. word_t et Manipulation de bits
    Par fmichael dans le forum C#
    Réponses: 2
    Dernier message: 19/03/2007, 09h33
  3. [VS 2005] Manipuler des bits
    Par b_lob dans le forum C#
    Réponses: 5
    Dernier message: 05/02/2007, 09h51
  4. [Ada] Manipulation de "Bits"
    Par BoBy9 dans le forum Ada
    Réponses: 2
    Dernier message: 14/06/2006, 11h57
  5. Manipulation de bits
    Par Tsly dans le forum C++
    Réponses: 2
    Dernier message: 28/09/2005, 12h41

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