[Résolu] Equivalents de BITSET, BITCLR, BITREV, BITTST ?

berfisberfis Membre
avril 2015 modifié dans API AppKit #1

Bonsoir, 


 


Il existait dans CarbonLib des fonctions sympas (des macros peut-être) qui effectuaient des opérations sur les bits d'un entier (court, long, indifféremment). La syntaxe générale était:


 


FONCTION (Adresse, bitN°).


 


Existe-t-il (je n'ai pas trouvé) l'equivalent quelque part? Je me suis coltiné avec les ^, ~, &, |, << et je ne trouve pas cela super lisible... J'aimerais bien ne pas avoir à  commenter chaque opération pour me souvenir de ce qu'elle est censée faire  <_<


 


Quelqu'un sait-il quelque chose à  ce sujet? Au pire, comment rédiger la macro?


Mots clés:

Réponses

  • Merci Joanna,


     


    Je suis sur ces pages depuis des heures, j'en arrive à  écrire des trucs comme ça:



    - (void) setActive:(BOOL)active {if (active)self.state = self.state | sActive; else self.state =self.state & ~sActive;}

    Alors que j'aimerai avoir ça:



    - (void) setActive:(BOOL)active {BITSET(state,activeBit,active);}

    ...


  • Qu'est-ce qui te manque pour écrire ces macros toi-même ?
  • Joanna CarterJoanna Carter Membre, Modérateur

    Comme ceci :



    #define BitsetHasValue(options, value) (((options) & (value)) == (value))
  • AliGatorAliGator Membre, Modérateur

    C'est pas la mort à  créer :


    #define BITMASKSET(byte, mask) byte | mask
    #define BITMASKUNSET(byte, mask) byte & ~mask
    #define BITMASK(bitIdx) 1<<bitIdx
    #define BITSET(byte, bitIdx) BITMASKSET(byte, BITMASK(bitIdx))
    #define BITUNSET(byte, bitIdx) BITMASKUNSET(byte, BITMASK(bitIdx))
    ...

  • moi, j'aime bien ça:


     


    #define BITSET(val, index, set) (set) ? val|(1<<index) : val& (~(1<<index))


     


    int v=0x100;


    v=BITSET(v,2,YES);  // -> 0x104


    v=BITSET(v,2,NO);  // -> 0x100


  • AliGatorAliGator Membre, Modérateur

    Attention mpergrand à  bien rajouter des parenthèses un peu partout dans tes macros. En effet tu n'as pas mis de parenthèses autour de val ni de index, donc en particulier si tu appelles BITSET(1+3*2,2,YES) ça ne va pas faire ce que tu penses ;)


  • Il aurait pu les faire lui-même... >:(




  • Attention mpergrand à  bien rajouter des parenthèses un peu partout dans tes macros. En effet tu n'as pas mis de parenthèses autour de val ni de index, donc en particulier si tu appelles BITSET(1+3*2,2,YES) ça ne va pas faire ce que tu penses ;)




     


    C'est la remarque que je voulais faire sur ton post précédent, mais je n'ai pas osé  ::)



  • Attention mpergrand à  bien rajouter des parenthèses un peu partout dans tes macros. En effet tu n'as pas mis de parenthèses autour de val ni de index, donc en particulier si tu appelles BITSET(1+3*2,2,YES) ça ne va pas faire ce que tu penses ;)




     


    oui, les effets de bord habituels des macros ...


    Perso, dans ce cas, je ferais plutôt une fonction inline.

  • J'ai assez de parenthèses?



    #define BITTST(var,index) (((var) & (1<<(index)))==(1<<(index)))
  • C'est du LISP ?


  • Bien qu'admirateur de Douglas Hofstadter, je n'ai jamais pratiqué le Lisp  :)


     


    Moi, on me dit "faut mettre des parenthèses", j'en mets, hein! Je ne prends plus le risque de courroucer les Grands Anciens ou d'indisposer Cthulhu...


  • Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

  • mpergandmpergand Membre
    avril 2015 modifié #16


     


    J'ai assez de parenthèses?



    #define BITTST(var,index) (((var) & (1<<(index)))==(1<<(index)))



     


    oui, il faut isoler chaque expression par des parenthèses pour éviter les effets de bord des macros.


     


    Une alternative serait une fonction inline.


    En C pur, dans un ficher .h, ça donnerait:



    #include <stdint.h>
    #include <stdbool.h>

    static inline uint64_t BITSET(uint64_t v, uint8_t index, bool set)
    {

    if (set) return (v | (1<<index));

    return (v & ~(1<<index));
    }



  • mpergand,


     


    J'aurais tendance à  préférer ta solution inline, personnellement. Même si le compilateur optimisera sans doute les deux solutions, j'ai l'impression de mieux "contrôler" ce qui se passe dans une fonction que dans la salade du #define. En plus, en termes de réutilisation, il n'y a pas photo...


     


    Mille mercis en tout cas.


     


    PS: j'ai besoin de ces fonctions pour contrôler l'état d'un objet (et aligner l'état d'autres objets qui dépendent de lui), les flags ne sont donc pas un caprice, mais une solution économique et extensible).


Connectez-vous ou Inscrivez-vous pour répondre.