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++Builder Discussion :

Entier : accès bit à bit


Sujet :

C++Builder

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 137
    Points : 161
    Points
    161
    Par défaut Entier : accès bit à bit
    Bonjour,

    Voila, je veux stocker plusieurs informations binaire dans un entier : le plus simple serait d'avoir accès à chaque bit de l'entier et que chaque bit ait un nom précis...

    J'ai déjà vu cela quelque part mais je ne sais plus où...

    Merci pour vos réponse.
    Sly.

  2. #2
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Bonjour,

    il faut faire une union de struct, si je me souviens bien.

    Cela définit ainsi plusieurs façons d'accéder à une donnée.

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Les champs de bits :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct Bitset
    {
        unsigned char Bit0 : 1,
                      Bit1 : 1,
                      Bit2 : 1,
                      ...
    };
    Tu as aussi std::bitset dans la STL.

  4. #4
    Membre habitué

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 137
    Points : 161
    Points
    161
    Par défaut
    Merci beaucoup pour cette réponse rapide.

    donc en fait il faut faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    union TStatus
    {
        int _int;
        Bitset  _bitset;
    }

  5. #5
    CGi
    CGi est actuellement connecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 049
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 049
    Points : 8 272
    Points
    8 272
    Par défaut
    J'avais mis un exemple ici :
    http://chgi.developpez.com/tips1/#tips13

  6. #6
    Membre actif

    Homme Profil pro
    Lycéen
    Inscrit en
    Décembre 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 44
    Points : 298
    Points
    298
    Par défaut
    il est aussi possible d'utiliser les opérateurs binaires (sur un int ou un char par ex.) comme &, |, << et >>. c'est plus C que C++ mais bien plus efficace.

    un exemple d'application se trouve à http://c.developpez.com/sources/bcb/?page=mathsalgo#hcd.

    cryptonyx

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Je suis d'accord avec cryptonyx !
    On peut très bien y associer des symboliques pour nommer chaque bit, comme pour la modélisation de certains µ (M68HC11 etc...) afin de mieux montrer ce que l'on fait !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define bit0 0x01
    #define bit1 0x02
    #define bit2 0x04
    #define bit3 0x08
    #define bit4 0x10
    #define bit5 0x20
    #define bit6 0x40
    #define bit7 0x80
    Eventuellement, on peut aussi définir des masques pour au moins une opération
    (celle du Clear ou Reset sinon on utilise bitn ^ -1) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define mbit0 0xFE
    #define mbit1 0xFD
    #define mbit2 0xFB
    #define mbit3 0xF7
    #define mbit4 0xEF
    #define mbit5 0xDF
    #define mbit6 0xBF
    #define mbit7 0x7F
    Un fois que c'est fait... ce n'est plus à faire !


    A plus !

    J'ai corrigé l'erreur car j'avais écrit Set à la place de Reset ce qui était faux !

  8. #8
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Tout à fait d'accord, et ça doit être plus rapide que les champs de bits.

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Trap D
    ça doit être plus rapide que les champs de bits.
    Pas toujours... Les bitfields peuvent être plus optimisés que les masques binaires. Mais c'est suivant le compilateur, les capacités du processeur, le jeu d'instructions, le type de manip désirée, etc...

    Par contre, je n'ai remarqué de gain en faveurs des bitfields que sur des accès pour un seul bit : pour des groupes (genre 4 bits consécutifs d'un bitfield), ça semble identique entre les deux méthodes, du moins si l'on utilise intelligemment les masques.

    Gros gain en faveur des masques, par contre, lors des accès à des bits "séparés" et non-contigus. C'est aussi le cas dans le cadre d'un parcours bit à bit : on peut automatiser et optimiser plus finement qu'avec les bitfields.

  10. #10
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    je suis nettement en faveur de l'acces avec les opérateurs logiques et ou, xor, << >>.
    sur du code exporté sur micro oû les sources ont été recompilées avec GNU, le champ de bit est supporté mais avec une lenteur à toute epreuve!.
    par ailleurs si on commence à avoir des structures avec des array de champ de bits, il commence a être incertain de conaitre avec certitude les offset des champs. SizeOf sort des choses parfois etonante comme sizeof( structure ) != somme sizeof( elements de la structure). Il m'a semblé que l'on avait ce genre de problèmes si on 'desalignait' les data sur les bytes ou words. comme par exemple mettre 2 bits puis un short puis encore 1 bit...
    J'evite donc ces champs trop 'compilateur dependant' .

  11. #11
    Membre habitué

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 137
    Points : 161
    Points
    161
    Par défaut
    Je faisais avant des acces avec les opérateurs logiques. Mais j'avais vu quelque part (c'était donc dans les tips de CGi ) la méthode des champs de bits et j'avais bien aimé. Je trouve cette méthode plus propre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    union TStatus
    {
      struct TBitset
      {
        unsigned char WARNING1 : 1,
                      WARNING2 : 1,
                      ERROR1 : 1,
                      ERROR2 : 1,
                       ...
      };
      TBitset _bitset;
      int _int;
    };
    Au niveau de la vitesse d'accès, je m'en fout un peu (à part si ça avait été très lent mais ce n'est pas le cas). Et je n'utilise jamais le sizeof... L'interêt est que mon code est plus propre !

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par j.p.mignot
    SizeOf sort des choses parfois etonante comme sizeof( structure ) != somme sizeof( elements de la structure).
    En fait, c'est normal : la taille par défaut (et la seule "officielle") d'un entier "bitfieldé", c'est le "int"... Donc, c'est 32 bits en général, parfois 16 suivant les plate-formes.
    Si tu définis ta structure ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
       unsigned char Field1 : 1 ;
       unsigned char Field2 : 2 ;
       unsigned char Field3 : 2 ;
       unsigned char Field4 : 3 ;
    } CCharBitfield ;
    Tu peux croire qu'effectivement, "sizeof(CCharBitfield)==sizeof(unsigned char)==1"... Mais ça peut être faux, ce n'est qu'une tolérance du compilateur, ou une option de compilation qui permettra cette égalité.
    Seule cette déclaration t'assure l'égalité quel que soit le compilateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    typedef struct {
       int Field1 : 1 ;
       int Field2 : 2 ;
       int Field3 : 2 ;
       int Field4 : 3 ;
       int unused : 8 ;
    #if (sizeof(int)==4)
       int fill   :16 ;
    #endif
    } CIntBitfield ;
    Mais encore faut-il que le préprocesseur accepte les évaluations "sizeof"... Et j'avoue qu'il n'est pas toujours facile de savoir quoi faire des 24 bits qui restent !! ;-)

  13. #13
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    C'est sur et sur un PC ou la mémoire est "infinie" cela n'est pas trop important quoi que j'ai sauvé des fichiers binaires sous un environnement delphi 3.x autant que je me souvienne qui ont du mal à être relu par la suite tant BC++ 6 que delphi 7 du à un autre allignement de variable. On s'en sort mais quand cela arrive chez des clients avec risque de perte de données c'et 1 autre histoire.
    Mais si le code doit être porté sur un micro où la mémoire est comptée et chaque byte est sujet à négociation j'évite les champs de bits peu côntrolables.

  14. #14
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par j.p.mignot
    Mais si le code doit être porté sur un micro où la mémoire est comptée et chaque byte est sujet à négociation j'évite les champs de bits peu côntrolables.
    Tu sais, mon boulot, c'est surtout et avant tout de l'embarqué, alors crois-moi, non seulement je connais le problème, mais en plus je compatis de tout coeur...
    Et ce n'est pas une vanne : pour avoir implémenté plusieurs protocoles de communication, c'est souvent un enfer de faire coller les structures C sur des structure de normes/RFC...

    C'était surtout pour t'indiquer que c'est "normal" que le sizeof d'un bitfield soit un peu loufoque... Faut utiliser quelques ruses de sioux (et bien connaître sa plate-forme) pour s'en sortir sans risques, mais la compilation conditionnelle reste de rigueur presque à chaque fois.

  15. #15
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    bonjour,
    les problèmes d'alignement de structures , champ de bits sont facilement résolvables avec les directives <#pragma> connues de la plupart des compilateurs C et C++

    exemple pour aligner une structure sur un bit il suffit de ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #pragma pack(push, 1)  // alignement sur 1 bit
    struct TmoitiedeByte
      {
      unsigned int Bits : 4;
      };
     
    #pragma pack(pop) //avec c++ Builder retour à l'alignement standard Quad Word aligne sur une frontière de 64 bits. Les données dont la taille de type est inférieure à 8 octets sont alignés sur la taille de leur type.
    cordialement

  16. #16
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    OK cela est sur mais que de place perue si on aligne des boolean a 1 bit sur des int à 32 bits!

  17. #17
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    bonjour,
    OK cela est sur mais que de place perue si on aligne des boolean a 1 bit sur des int à 32 bits!
    tu n'a pas compris ce que j'ai voulu dire par défault l'alignenemnt est sous C++ Builder le Quad Word aligne sur une frontière de 64 bits. Les données dont la taille de type est inférieure à 8 octets sont alignés sur la taille de leur type.

    en utilisant les directives praga on peut dans son code chnager l'alignement par exemple sous 1 bit avec la directive <#pragma pack(push, 1) >

    cordialement

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

Discussions similaires

  1. [C#] Conversion chaîne vers entier signé 8 bits
    Par SesechXP dans le forum Windows Forms
    Réponses: 2
    Dernier message: 25/09/2006, 14h29
  2. Réponses: 1
    Dernier message: 27/07/2006, 16h58
  3. Insérer un entier sur 64 bits dans une base ?
    Par DJZiaK dans le forum SQLite
    Réponses: 1
    Dernier message: 10/05/2005, 17h37
  4. entiers de 64 bits
    Par jmv dans le forum C++
    Réponses: 11
    Dernier message: 15/09/2004, 20h52
  5. [8086] Affichage d'un entier de 32 bits
    Par elNINIo dans le forum Assembleur
    Réponses: 12
    Dernier message: 10/05/2003, 20h33

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