Comment définissez-vous, effacer et basculer un seul bit?

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

2117
demandé sur WaleedYaser 2008-09-07 04:42:17

26 réponses

Définir un bit

Utiliser l'opérateur or (|) pour définir un bit.

number |= 1UL << n;

Cela va définir le nth bit de number.

Utilisez 1ULL Si number est plus large que unsigned long; la promotion de 1UL << n ne se produit qu'après avoir évalué 1UL << n où son comportement indéfini se déplace de plus de la largeur d'un long. La même chose s'applique à tous les autres exemples.

Effacer un peu

Utilisez l'opérateur and (&) pour effacer un bit.

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

Cela effacera le nth bit de number. Vous devez inverser la chaîne de bits avec l'opérateur bitwise NOT (~), then ET it.

Basculer un peu

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

number ^= 1UL << n;

Qui va basculer le nth bit de number.

Vérifier un peu

Vous n'avez pas demandé ça, mais je pourrais aussi bien l'ajouter.

Pour vérifier un bit, déplacez le nombre n vers la droite, puis il:

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

Cela mettra la valeur du nth bit de number dans la variable bit.

Modification de la n - ième bit de x

Définir le nth bit sur 1 ou 0 peut être réalisé avec ce qui suit sur l'implémentation C++ d'un complément 2:

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

Bits n sera réglé que si x est 1, et effacé si x est 0. Si x a une autre valeur, vous obtenez des ordures. {[35] } va le booleaniser à 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 à l'implémentation C++ du complément ou du signe/magnitude 1), 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 portables.

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

3077
répondu Jeremy Ruten 2018-07-24 18:42:18

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

Ou la versionBoost : boost::dynamic_bitset.

Il N'y a pas besoin de rouler votre propre:

#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 bitset de taille runtime par rapport à unbibliothèque standard bitset de taille compile.

392
répondu Martin York 2018-02-16 01:18:57

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 de bits deviennent maintenant 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 */

Vérifier 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 bit-twiddling décrites dans les messages précédents.

216
répondu Ferruccio 2012-11-29 00:40:32

J'utilise des macros définies dans un fichier d'en-tête pour gérer bit set et clear:

/* 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)))

/* 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))
127
répondu Steve Karg 2017-11-10 21:30:17

Il vaut parfois la peine d'utiliser un enum pourNom les bits:

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

Ensuite, utilisez les 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 cachez les nombres magiques du reste de votre code.

À part ça, j'approuve la solution de Jeremy.

101
répondu dmckee 2013-10-18 15:54:21

De snip-c.zip les bitops de .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 commune avec laquelle vous semblez avoir des problèmes dans tout cela est "(1L

    0000 0000 0000 0000 0000 0000 0000 0001 binary.

Si posn= = 8, il évaluera à

    0000 0000 0000 0000 0000 0001 0000 0000 binary.

Dans les autres mots, il crée simplement un champ de 0 avec un 1 au spécifié position. La seule partie délicate est dans la macro BitClr() où nous devons définir un seul bit 0 dans un champ de 1. Ceci est accompli en utilisant les 1 complément de la même expression que celle indiquée par l'opérateur tilde ( ~ ).

Une fois le masque créé, il est appliqué à l'argument comme vous le suggérez, en utilisant les opérateurs bit à bit et (&), ou ( | ) et xor ( ^ ). Puisque le masque est de type long, les macros fonctionneront tout comme bien sur char, short, int, ou de long.

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

Pas convaincu? Voici un code de test - J'ai utilisé Watcom C avec une optimisation complète et sans utiliser _cdecl, le démontage résultant 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

----[ finis ]-----------------------------------------------------------------

35
répondu yogeesh 2018-03-07 15:07:16

Pour le débutant que je voudrais expliquer un peu plus avec un exemple:

Exemple:

value is 0x55;
bitnum : 3rd.

L'opérateur & est utilisé vérifiez 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)

Bascule ou bascule:

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

| opérateur: définir le bit

0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
29
répondu kapilddit 2015-05-22 16:09:54

Utiliser les opérateurs binaires: & |

Pour définir le dernier bit dans 000b:

foo = foo | 001b

Pour vérifier le dernier bit dans foo:

if ( foo & 001b ) ....

Pour effacer le dernier bit dans foo:

foo = foo & 110b

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

28
répondu nsanders 2018-04-12 11:23:14

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

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

Pour définir un bit:

BITOP(array, bit, |=);

Pour effacer un peu:

BITOP(array, bit, &=~);

Pour basculer un peu:

BITOP(array, bit, ^=);

Pour tester un peu:

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

Etc.

24
répondu R.. 2013-05-09 14:21:00

Comme il est étiqueté "embedded", 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 ont 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 / basculement ISR haute fréquence piges.

Pour ceux qui ne sont pas familiers: dans mon exemple, le micro a un Portn de Registre général d'état de broche qui reflète les broches de sortie, Donc PORTn / = BIT_TO_SET entraîne une lecture-modification-écriture dans ce registre. Cependant, les registres PORTnSET / PORTnCLEAR prennent un ' 1 'pour signifier" please make this bit 1 "(SET) ou" please make this bit zero "(CLEAR) et un '0' pour signifier"laisser le code PIN seul". donc, vous vous retrouvez avec deux adresses de port selon que vous définissez ou effacez le bit (pas toujours pratique) mais une réaction beaucoup plus rapide et un code assemblé plus petit.

22
répondu John U 2012-06-14 15:23:17

L'approche bitfield présente d'autres avantages dans l'arène embarquée. 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 MSB d'abord, mais cela peut dépendre de l'implémentation. Vérifiez également comment les champs de vos gestionnaires de compilateur traversent les limites des octets.

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

21
répondu Roddy 2008-11-06 11:30:16

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)))
19
répondu bill 2009-06-15 07:38:21

Vérifier 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;
}

Notes: Ceci est conçu pour être rapide (compte tenu de sa flexibilité) et non ramifié. Il en résulte un code machine SPARC efficace lors de la compilation 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 que cela fonctionne pour n'importe quel endroit dans pratiquement n'importe quel type de variable.

17
répondu John Zwinck 2009-01-03 23:44:14

Si vous faites beaucoup de twiddling, vous voudrez peut-être utiliser des masques qui rendront le tout plus rapide. Les fonctions suivantes sont très rapides et sont toujours flexibles (elles permettent de tourner des bits dans des cartes de bits 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;
}

Remarque, 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 nombre de bits est dans la plage de la carte de bits que vous passez. Notez que pour little endian processeurs d'octets, de mots, dword, qwords, etc., carte correctement les uns aux autres en mémoire (raison principale que les processeurs little endian sont "meilleurs" que les processeurs big-endian, ah, je sens une guerre de flamme à venir...).

13
répondu Tim Ring 2017-12-05 11:20:35

Ce programme est de changer toutes les données bits 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);
        }
    }
}
12
répondu Gokul Naathan 2015-05-22 16:07:42

Utilisez ceci:

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

    return num;
}
11
répondu Peter Mortensen 2015-05-22 16:06:03

Expansion de la réponse bitset:

#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;
}
9
répondu kendotwill 2014-05-08 04:33:41

Si vous voulez effectuer toute cette opération avec la programmation C dans le noyau Linux alors je suggère d'utiliser des API standard 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 passe en une seule étape. Donc, tous ceux-ci sont garantis atomic même sur les ordinateurs SMP et sont utiles pour maintenir la cohérence entre les processeurs.

9
répondu Jeegar Patel 2017-12-01 16:21:28

Visual C 2010, et peut-être beaucoup d'autres compilateurs, ont un support direct pour les opérations de bits intégrées. Étonnamment, cela fonctionne, même l'opérateur sizeof() 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);
}

Donc, à votre question, IsGph[i] = 1, ou IsGph[i] = 0 rendent le réglage et l'effacement des bools faciles.

Pour trouver 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" à propos de ce code. Il traite un peu comme un entier - ce qui techniquement, c'est le cas. Un entier de 1 bit pouvant contenir 2 valeurs et 2 valeurs seulement.

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

8
répondu 2014-08-03 05:51:00

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

Pour définir un bit, utilisez int x = x | 0x?;? est la position du bit sous forme binaire.

5
répondu Jason 2012-07-05 22:58:36

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)
4
répondu sam msft 2015-02-06 23:11:18

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

Pour traiter une codification commune piège lors d'une tentative pour former le masque:
1 n'est pas toujours assez large

Quels problèmes se produisent lorsque number est un type plus large que 1?
x peut-être trop grand pour la maj 1 << x conduisant à comportement indéfini (UB). Même si x n'est pas trop grand, ~ peut ne pas retourner assez 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 1 est assez large:

Le Code pourrait utiliser 1ull ou pedantiquement (uintmax_t)1 et laisser le compilateur optimiser.

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

Ou cast - ce qui rend les problèmes de codage/révision/maintenance en gardant la distribution correcte et à jour.

number |= (type_of_number)1 << x;

Ou promouvoir doucement le 1 en forçant une opération mathématique qui est aussi large que le type de number.

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

Comme avec la plupart des bits de manipulations, il est préférable de travailler avec unsigned les types plutôt que signée les uns

3
répondu chux 2017-09-27 18:18:48
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);
}
2
répondu Sazzad Hissain Khan 2018-02-21 12:35:12

Une version de 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;}
}
2
répondu Joakim L. Christiansen 2018-02-27 20:51:05

Variable utilisée

int value, pos;

Valeur-Données
pos-position du bit que nous sommes intéressés à définir, effacer ou basculer
définir un bit

value = value | 1 << pos;

Clair un peu

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

Bascule un peu

value = value ^ 1 << pos;
2
répondu Jeet Parikh 2018-07-11 17:32:56

Essayez l'une de ces fonctions dans le langage C pour changer 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;
}
-1
répondu Vincet 2018-02-16 01:20:23