Question

Comment définir, effacer et basculer un peu en C/C++ ?

Était-ce utile?

La solution

Régler un peu

Utilisez l'opérateur OU au niveau du bit (|) pour régler un peu.

number |= 1UL << n;

Cela définira le nle morceau de number. n devrait être zéro, si vous souhaitez définir le 1st bit et ainsi de suite jusqu'à n-1, si vous souhaitez définir le nle morceau.

Utiliser 1ULL si number est plus large que unsigned long;promotion de 1UL << n cela n'arrive qu'après l'évaluation 1UL << n où c'est un comportement indéfini de se décaler de plus que la largeur d'un long.La même chose s’applique à tous les autres exemples.

Dégage un peu

Utilisez l'opérateur ET au niveau du bit (&) pour clarifier un peu.

number &= ~(1UL << n);

Cela effacera le nle morceau de number.Vous devez inverser la chaîne de bits avec l'opérateur NOT au niveau du bit (~), puis ET il.

Basculer un peu

L'opérateur XOR (^) peut être utilisé pour basculer un peu.

number ^= 1UL << n;

Cela fera basculer le nle morceau de number.

Je vérifie un peu

Vous ne l'avez pas demandé, mais autant l'ajouter.

Pour vérifier un peu, décalez le nombre n vers la droite, puis au niveau du bit ET:

bit = (number >> n) & 1U;

Cela mettra la valeur du nle morceau de number dans la variable bit.

Changer le nle peu à X

Réglage du nle bit à l'un ou l'autre 1 ou 0 peut être réalisé avec ce qui suit sur une implémentation C++ en complément à 2 :

number ^= (-x ^ number) & (1UL << n);

Peu n sera défini si x est 1, et effacé si x est 0.Si x a une autre valeur, vous obtenez des déchets. x = !!x le booléenisera à 0 ou 1.

Pour rendre cela indépendant du comportement de négation du complément à 2 (où -1 a tous les bits définis, contrairement à une implémentation C++ de complément à 1 ou de signe/magnitude), utilisez la négation non signée.

number ^= (-(unsigned long)x ^ number) & (1UL << n);

ou

unsigned long newbit = !!x;    // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);

C'est généralement une bonne idée d'utiliser des types non signés pour la manipulation de bits portable.

ou

number = (number & ~(1UL << n)) | (x << n);

(number & ~(1UL << n)) effacera le nle morceau et (x << n) définira le nle peu à x.

C'est aussi généralement une bonne idée de ne pas copier/coller de code en général et de nombreuses personnes utilisent des macros de préprocesseur (comme la réponse du wiki de la communauté plus bas) ou une sorte d'encapsulation.

Autres conseils

Utilisation de la bibliothèque C++ standard : std::bitset<N>.

Ou la Booster version: boost::dynamic_bitset.

Il n'est pas nécessaire de rouler le vôtre :

#include <bitset>
#include <iostream>

int main()
{
    std::bitset<5> x;

    x[1] = 1;
    x[2] = 0;
    // Note x[0-4]  valid

    std::cout << x << std::endl;
}

[Alpha:] > ./a.out
00010

La version Boost permet un ensemble de bits de taille d'exécution par rapport à un bibliothèque standard Jeu de bits de la taille du moment de la compilation.

L'autre option consiste à utiliser des champs de bits :

struct bits {
    unsigned int a:1;
    unsigned int b:1;
    unsigned int c:1;
};

struct bits mybits;

définit un champ de 3 bits (en fait, il s'agit de trois champs de 1 bit).Les opérations sur les bits deviennent désormais un peu (haha) plus simples :

Pour définir ou effacer un peu :

mybits.b = 1;
mybits.c = 0;

Pour basculer un peu :

mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1;  /* all work */

Je vérifie un peu :

if (mybits.c)  //if mybits.c is non zero the next line below will execute

Cela ne fonctionne qu'avec des champs de bits de taille fixe.Sinon, vous devez recourir aux techniques de manipulation décrites dans les articles précédents.

J'utilise des macros définies dans un fichier d'en-tête pour gérer les bits définis et effacés :

/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b))))        // '!!' to make sure this returns 0 or 1

/* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK_ALL(x,y) (((x) & (y)) == (y))   // warning: evaluates y twice
#define BITMASK_CHECK_ANY(x,y) ((x) & (y))

Cela vaut parfois la peine d'utiliser un enum à nom les morceaux :

enum ThingFlags = {
  ThingMask  = 0x0000,
  ThingFlag0 = 1 << 0,
  ThingFlag1 = 1 << 1,
  ThingError = 1 << 8,
}

Utilisez ensuite le des noms plus tard.C'est à dire.écrire

thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}

pour définir, effacer et tester.De cette façon, vous masquez les nombres magiques du reste de votre code.

A part cela, j'approuve la solution de Jeremy.

Depuis snip-c.zip's bitops.h :

/*
**  Bit set, clear, and test operations
**
**  public domain snippet by Bob Stout
*/

typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;

#define BOOL(x) (!(!(x)))

#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))

OK, analysons les choses...

L'expression courante avec laquelle vous semblez avoir des problèmes dans tout cela est "(1L << (posn))".Tout cela est de créer un masque avec un seul bit et qui fonctionnera avec n'importe quel type entier.L'argument "POSN" spécifie la position où vous voulez le bit.Si POSN == 0, cette expression évaluera à:

0000 0000 0000 0000 0000 0000 0000 0001 binary.

Si posn==8, il sera évalué à :

0000 0000 0000 0000 0000 0001 0000 0000 binary.

En d'autres termes, il crée simplement un champ de 0 avec un 1 à la position spécifiée.La seule partie délicate se trouve dans la macro bitclr () où nous devons définir un seul bit 0 dans un champ de 1.Ceci est accompli en utilisant le complément 1 de la même expression que l'opérateur Tilde (~).

Une fois le masque créé, il est appliqué à l'argument comme vous le suggérez, en utilisant les opérateurs de bitwise et (&), ou (|) et xor (^).Étant donné que le masque est long, les macros fonctionneront tout aussi bien sur Char's, Short's, Int's ou Long's.

L'essentiel est qu'il s'agit d'une solution générale à toute une classe de problèmes.Il est, bien sûr, possible et même approprié de réécrire l'équivalent de l'une de ces macros avec des valeurs de masque explicites chaque fois que vous en avez besoin, mais pourquoi le faire?N'oubliez pas que la substitution macro se produit dans le préprocesseur et que le code généré reflètera le fait que les valeurs sont considérées comme constantes par le compilateur - c'est-à-direIl est tout aussi efficace d'utiliser les macros généralisées que de "réinventer la roue" chaque fois que vous devez faire des manipulations de bits.

Pas convaincu ?Voici un code de test - j'ai utilisé Watcom C avec une optimisation complète et sans utiliser _CDECL, donc le démontage qui en résulte serait aussi propre que possible:

----[ TEST.C ]-------------------------------------------------------- -----------------------

#define BOOL(x) (!(!(x)))

#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))

int bitmanip(int word)
{
      word = BitSet(word, 2);
      word = BitSet(word, 7);
      word = BitClr(word, 3);
      word = BitFlp(word, 9);
      return word;
}

----[ TEST.OUT (démonté) ]-------------------------------------- ---------

Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS

Segment: _TEXT  BYTE   00000008 bytes  
 0000  0c 84             bitmanip_       or      al,84H    ; set bits 2 and 7
 0002  80 f4 02                          xor     ah,02H    ; flip bit 9 of EAX (bit 1 of AH)
 0005  24 f7                             and     al,0f7H
 0007  c3                                ret     

No disassembly errors

----[ fini ]------------------------------------------------ ----------------------

Utilisez les opérateurs au niveau du bit : & |

Pour définir le dernier bit 000b:

foo = foo | 001b

Pour vérifier le dernier bit foo:

if ( foo & 001b ) ....

Pour effacer le dernier bit foo:

foo = foo & 110b

j'ai utilisé XXXb pour plus de clarté.Vous travaillerez probablement avec une représentation HEX, en fonction de la structure de données dans laquelle vous regroupez les bits.

Pour le débutant, j'aimerais expliquer un peu plus avec un exemple :

Exemple:

value is 0x55;
bitnum : 3rd.

Le & l'opérateur est utilisé pour vérifier le bit :

0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)

Basculer ou retourner :

0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)

| opérateur:régler le bit

0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)

Voici ma macro arithmétique de bits préférée, qui fonctionne pour tout type de tableau d'entiers non signés de unsigned char jusqu'à size_t (qui est le plus grand type avec lequel il devrait être efficace de travailler) :

#define BITOP(a,b,op) \
 ((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))

Pour régler un peu :

BITOP(array, bit, |=);

Pour clarifier un peu :

BITOP(array, bit, &=~);

Pour basculer un peu :

BITOP(array, bit, ^=);

Pour tester un peu :

if (BITOP(array, bit, &)) ...

etc.

L'approche bitfield présente d'autres avantages dans le domaine de l'embarqué.Vous pouvez définir une structure qui mappe directement sur les bits d'un registre matériel particulier.

struct HwRegister {
    unsigned int errorFlag:1;  // one-bit flag field
    unsigned int Mode:3;       // three-bit mode field
    unsigned int StatusCode:4;  // four-bit status code
};

struct HwRegister CR3342_AReg;

Vous devez être conscient de l'ordre d'emballage des bits - je pense que c'est d'abord MSB, mais cela peut dépendre de l'implémentation.Vérifiez également comment votre compilateur gère les champs dépassant les limites d'octets.

Vous pouvez alors lire, écrire, tester les valeurs individuelles comme auparavant.

Comme ceci est étiqueté « intégré », je suppose que vous utilisez un microcontrôleur.Toutes les suggestions ci-dessus sont valides et fonctionnent (lecture-modification-écriture, unions, structures, etc.).

Cependant, lors d'un débogage basé sur un oscilloscope, j'ai été étonné de constater que ces méthodes entraînent une surcharge considérable en cycles CPU par rapport à l'écriture d'une valeur directement dans les registres PORTnSET/PORTnCLEAR du micro, ce qui fait une réelle différence là où il y a des boucles serrées/hautes. -les broches à bascule de l'ISR à fréquence.

Pour ceux qui ne connaissent pas :Dans mon exemple, le micro a un registre général d'état des broches PORTn qui reflète les broches de sortie, donc faire PORTn |= BIT_TO_SET entraîne une lecture-modification-écriture dans ce registre.Cependant, les registres PORTnSET / PORTnCLEAR prennent un « 1 » pour signifier « veuillez mettre ce bit à 1 » (SET) ou « veuillez mettre ce bit à zéro » (CLEAR) et un « 0 » pour signifier « laissez la broche tranquille ».donc, vous vous retrouvez avec deux adresses de port selon que vous définissez ou effacez le bit (pas toujours pratique) mais un beaucoup une réaction plus rapide et un code assemblé plus petit.

Plus général, pour les bitmaps de taille arbitraire :

#define BITS 8
#define BIT_SET(  p, n) (p[(n)/BITS] |=  (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] &   (0x80>>((n)%BITS)))

Vérifiez un peu à un emplacement arbitraire dans une variable de type arbitraire :

#define bit_test(x, y)  ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )

Exemple d'utilisation :

int main(void)
{
    unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };

    for (int ix = 0; ix < 64; ++ix)
        printf("bit %d is %d\n", ix, bit_test(arr, ix));

    return 0;
}

Remarques:Ceci est conçu pour être rapide (compte tenu de sa flexibilité) et sans branchement.Il en résulte un code machine SPARC efficace lorsqu'il est compilé avec Sun Studio 8 ;Je l'ai également testé en utilisant MSVC++ 2008 sur amd64.Il est possible de créer des macros similaires pour définir et effacer les bits.La principale différence de cette solution par rapport à beaucoup d'autres ici est qu'elle fonctionne pour n'importe quel emplacement dans à peu près n'importe quel type de variable.

Ce programme consiste à changer n'importe quel bit de données de 0 à 1 ou de 1 à 0 :

{
    unsigned int data = 0x000000F0;
    int bitpos = 4;
    int bitvalue = 1;
    unsigned int bit = data;
    bit = (bit>>bitpos)&0x00000001;
    int invbitvalue = 0x00000001&(~bitvalue);
    printf("%x\n",bit);

    if (bitvalue == 0)
    {
        if (bit == 0)
            printf("%x\n", data);
        else
        {
             data = (data^(invbitvalue<<bitpos));
             printf("%x\n", data);
        }
    }
    else
    {
        if (bit == 1)
            printf("elseif %x\n", data);
        else
        {
            data = (data|(bitvalue<<bitpos));
            printf("else %x\n", data);
        }
    }
}

Si vous faites beaucoup de manipulations, vous voudrez peut-être utiliser des masques qui rendront le tout plus rapide.Les fonctions suivantes sont très rapides et restent flexibles (elles permettent de modifier les bits dans des bitmaps de n'importe quelle taille).

const unsigned char TQuickByteMask[8] =
{
   0x01, 0x02, 0x04, 0x08,
   0x10, 0x20, 0x40, 0x80,
};


/** Set bit in any sized bit mask.
 *
 * @return    none
 *
 * @param     bit    - Bit number.
 * @param     bitmap - Pointer to bitmap.
 */
void TSetBit( short bit, unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;        // Index to byte.
    n = bit % 8;        // Specific bit in byte.

    bitmap[x] |= TQuickByteMask[n];        // Set bit.
}


/** Reset bit in any sized mask.
 *
 * @return  None
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
void TResetBit( short bit, unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;        // Index to byte.
    n = bit % 8;        // Specific bit in byte.

    bitmap[x] &= (~TQuickByteMask[n]);    // Reset bit.
}


/** Toggle bit in any sized bit mask.
 *
 * @return   none
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
void TToggleBit( short bit, unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;        // Index to byte.
    n = bit % 8;        // Specific bit in byte.

    bitmap[x] ^= TQuickByteMask[n];        // Toggle bit.
}


/** Checks specified bit.
 *
 * @return  1 if bit set else 0.
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
short TIsBitSet( short bit, const unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;    // Index to byte.
    n = bit % 8;    // Specific bit in byte.

    // Test bit (logigal AND).
    if (bitmap[x] & TQuickByteMask[n])
        return 1;

    return 0;
}


/** Checks specified bit.
 *
 * @return  1 if bit reset else 0.
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
short TIsBitReset( short bit, const unsigned char *bitmap)
{
    return TIsBitSet(bit, bitmap) ^ 1;
}


/** Count number of bits set in a bitmap.
 *
 * @return   Number of bits set.
 *
 * @param    bitmap - Pointer to bitmap.
 * @param    size   - Bitmap size (in bits).
 *
 * @note    Not very efficient in terms of execution speed. If you are doing
 *        some computationally intense stuff you may need a more complex
 *        implementation which would be faster (especially for big bitmaps).
 *        See (http://graphics.stanford.edu/~seander/bithacks.html).
 */
int TCountBits( const unsigned char *bitmap, int size)
{
    int i, count = 0;

    for (i=0; i<size; i++)
        if (TIsBitSet(i, bitmap))
            count++;

    return count;
}

Notez que pour définir le bit 'n' dans un entier de 16 bits, procédez comme suit :

TSetBit( n, &my_int);

C'est à vous de vous assurer que le numéro de bit se situe dans la plage du bitmap que vous transmettez.Notez que pour les processeurs little endian, les octets, les mots, les dwords, les qwords, etc., sont correctement mappés les uns aux autres en mémoire (raison principale pour laquelle les processeurs small endian sont « meilleurs » que les processeurs big-endian, ah, je sens une guerre des flammes arriver sur...).

Utilisez ceci:

int ToggleNthBit ( unsigned char n, int num )
{
    if(num & (1 << n))
        num &= ~(1 << n);
    else
        num |= (1 << n);

    return num;
}

S'étendre sur le bitset répondre:

#include <iostream>
#include <bitset>
#include <string>

using namespace std;
int main() {
  bitset<8> byte(std::string("10010011");

  // Set Bit
  byte.set(3); // 10010111

  // Clear Bit
  byte.reset(2); // 10010101

  // Toggle Bit
  byte.flip(7); // 00010101

  cout << byte << endl;

  return 0;
}

Si vous souhaitez effectuer toutes ces opérations avec la programmation C dans le Noyau Linux alors je suggère d'utiliser les API standards du noyau Linux.

Voir https://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html

set_bit  Atomically set a bit in memory
clear_bit  Clears a bit in memory
change_bit  Toggle a bit in memory
test_and_set_bit  Set a bit and return its old value
test_and_clear_bit  Clear a bit and return its old value
test_and_change_bit  Change a bit and return its old value
test_bit  Determine whether a bit is set

Note:Ici, toute l’opération se déroule en une seule étape.Donc tout cela est garanti atomique Même sur les ordinateurs SMP et sont utiles pour maintenir la cohérence entre les processeurs.

Visual C 2010, et peut-être de nombreux autres compilateurs, prennent directement en charge les opérations sur les bits.Étonnamment, cela fonctionne, même sizeof() l'opérateur fonctionne correctement.

bool    IsGph[256], IsNotGph[256];

//  Initialize boolean array to detect printable characters
for(i=0; i<sizeof(IsGph); i++)  {
    IsGph[i] = isgraph((unsigned char)i);
}

Alors, à votre question, IsGph[i] =1, ou IsGph[i] =0 facilitent la configuration et la suppression des bools.

Pour rechercher des caractères non imprimables :

//  Initialize boolean array to detect UN-printable characters, 
//  then call function to toggle required bits true, while initializing a 2nd
//  boolean array as the complement of the 1st.
for(i=0; i<sizeof(IsGph); i++)  {
    if(IsGph[i])    {
         IsNotGph[i] = 0;
    }   else   {
         IsNotGph[i] = 1;
    }
}

Notez qu'il n'y a rien de "spécial" dans ce code.Il se traite un peu comme un entier – ce qui est techniquement le cas.Un entier de 1 bit pouvant contenir 2 valeurs et 2 valeurs uniquement.

Une fois, j'ai utilisé cette approche pour trouver des enregistrements de prêt en double, où prêt_numéro était la clé ISAM, en utilisant le numéro de prêt à 6 chiffres comme index dans le tableau de bits.Très rapidement, et après 8 mois, nous avons prouvé que le système mainframe à partir duquel nous obtenions les données fonctionnait en fait mal.La simplicité des tableaux de bits rend la confiance dans leur exactitude très élevée - par rapport à une approche de recherche par exemple.

Utilisez l'un des opérateurs tels que définis ici.

Pour régler un peu, utilisé int x = x | 0x?;? est la position du bit sous forme binaire.

Voici quelques macros que j'utilise :

SET_FLAG(Status, Flag)            ((Status) |= (Flag))
CLEAR_FLAG(Status, Flag)          ((Status) &= ~(Flag))
INVALID_FLAGS(ulFlags, ulAllowed) ((ulFlags) & ~(ulAllowed))
TEST_FLAGS(t,ulMask, ulBit)       (((t)&(ulMask)) == (ulBit))
IS_FLAG_SET(t,ulMask)             TEST_FLAGS(t,ulMask,ulMask)
IS_FLAG_CLEAR(t,ulMask)           TEST_FLAGS(t,ulMask,0)

Variable utilisée

int value, pos;

données de valeur
pos - position du bit que nous souhaitons définir, effacer ou activer.

Réglez un peu :

value = value | 1 << pos;

Clair un peu :

value = value & ~(1 << pos); 

Basculez un peu :

value = value ^ 1 << pos;

Comment définir, effacer et activer un seul bit ?

Pour résoudre un problème de codage courant lors de la tentative de création du masque :
1 n'est pas toujours assez large

Quels problèmes surviennent quand number est un type plus large que 1?
x c'est peut-être trop important pour le changement 1 << x menant à comportement indéfini (UB).Même si x ce n'est pas trop génial, ~ peut ne pas retourner suffisamment de bits les plus significatifs.

// assume 32 bit int/unsigned
unsigned long long number = foo();

unsigned x = 40; 
number |= (1 << x);  // UB
number ^= (1 << x);  // UB
number &= ~(1 << x); // UB

x = 10;
number &= ~(1 << x); // Wrong mask, not wide enough

Pour assurer que 1 est suffisamment large :

Le code pourrait utiliser 1ull ou pédant (uintmax_t)1 et laissez le compilateur optimiser.

number |= (1ull << x);
number |= ((uintmax_t)1 << x);

Ou casting - ce qui entraîne des problèmes de codage/révision/maintenance pour maintenir le casting correct et à jour.

number |= (type_of_number)1 << x;

Ou favorisez doucement le 1 en forçant une opération mathématique au moins aussi large que le type de number.

number |= (number*0 + 1) << x;

Comme pour la plupart des manipulations de bits, il est préférable de travailler avec non signé types plutôt que signé ceux

int set_nth_bit(int num, int n){    
    return (num | 1 << n);
}

int clear_nth_bit(int num, int n){    
    return (num & ~( 1 << n));
}

int toggle_nth_bit(int num, int n){    
    return num ^ (1 << n);
}

int check_nth_bit(int num, int n){    
    return num & (1 << n);
}

Une version basée sur un modèle C++11 (mise dans un en-tête) :

namespace bit {
    template <typename T1, typename T2> inline void set  (T1 &variable, T2 bit) {variable |=  ((T1)1 << bit);}
    template <typename T1, typename T2> inline void clear(T1 &variable, T2 bit) {variable &= ~((T1)1 << bit);}
    template <typename T1, typename T2> inline void flip (T1 &variable, T2 bit) {variable ^=  ((T1)1 << bit);}
    template <typename T1, typename T2> inline bool test (T1 &variable, T2 bit) {return variable & ((T1)1 << bit);}
}

namespace bitmask {
    template <typename T1, typename T2> inline void set  (T1 &variable, T2 bits) {variable |= bits;}
    template <typename T1, typename T2> inline void clear(T1 &variable, T2 bits) {variable &= ~bits;}
    template <typename T1, typename T2> inline void flip (T1 &variable, T2 bits) {variable ^= bits;}
    template <typename T1, typename T2> inline bool test_all(T1 &variable, T2 bits) {return ((variable & bits) == bits);}
    template <typename T1, typename T2> inline bool test_any(T1 &variable, T2 bits) {return variable & bits;}
}

Essayez l'une de ces fonctions en langage C pour modifier n bits :

char bitfield;

// Start at 0th position

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}

Ou

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}

Ou

void chang_n_bit(int n, int value)
{
    if(value)
        bitfield |= 1 << n;
    else
        bitfield &= ~0 ^ (1 << n);
}

char get_n_bit(int n)
{
    return (bitfield & (1 << n)) ? 1 : 0;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top