Comment définissez-vous, Clarifiez-vous et basculez-vous un seul peu?

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

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

26 ответов

réglage d'un bit

utilisez le bitwise ou l'opérateur ( | ) pour régler un bit.

number |= 1UL << n;

qui définira le n e bit de number .

utiliser 1ULL si number est plus large que unsigned long ; la promotion de 1UL << n ne se produit pas avant après avoir évalué 1UL << n où il est un comportement non défini de se déplacer de plus de la largeur d'un long . La même chose s'applique à tout le reste des exemples.

effacer un peu

utilisez le bitwise et l'opérateur ( & ) pour effacer un bit.

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

qui nettoiera le n TH bit de number . Vous devez inverser la chaîne de bits avec le bitwise pas l'opérateur ( ~ ), puis et il.

Basculer un peu

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

number ^= 1UL << n;

qui va basculer le n TH bit de number .

Vérification un peu

Vous n'avez pas demandé, mais je peux bien ajouter.

pour vérifier un bit, déplacer le nombre n vers la droite, puis bitwise et it:

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

qui placera la valeur du n e bit de number dans la variable bit .

changer le n TH bit en x

le réglage du n TH bit à 1 ou 0 peut être réalisé avec ce qui suit sur une implémentation C++ de type 2:

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

Bit n sera défini si x est 1 , et autorisé si x est 0 . Si x a une autre valeur, vous obtenez des ordures. x = !!x va booleaniser à 0 ou 1.

pour rendre cela indépendant du comportement de négation du complément de 2 (où -1 a tous les bits mis, contrairement au complément de 1 ou à l'implémentation C++ de sign/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 portables.

il est également 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 préprocesseur (comme la réponse wiki communautaire plus bas ) ou une sorte d'encapsulation.

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

en utilisant la bibliothèque Standard C++ : std::bitset<N> .

ou la version Boost : 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 d'exécution comparé à un bibliothèque standard bitset de taille de compilation.

392
répondu Martin York 2018-02-16 04:18:57
la source

l'autre option est d'utiliser les 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, c'est trois champs de 1 bit). Les opérations de bits deviennent maintenant un peu plus simples (haha):

pour régler 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 bit de taille fixe. Sinon, vous devrez recourir à la les techniques de bit-twiddling décrites dans les billets précédents.

216
répondu Ferruccio 2012-11-29 04:40:32
la source

j'utilise des macros définies dans un fichier d'en-tête pour gérer le 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-11 00:30:17
la source

il est parfois utile d'utiliser un enum à nom les bits:

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

, Puis utiliser le noms plus tard. I. e. écrire

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

à régler, effacer et tester. De cette façon, vous cachez les nombres magiques du reste de votre code.

à part que j'approuve la solution de Jeremy.

101
répondu dmckee 2013-10-18 19:54:21
la source

de snip-c.zip est 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 tous ces cas est"(1L << (postN))". Tout cela n'est de créer un masque avec un seul bit sur et qui fonctionnera avec n'importe quel type entier. L'argument "posn" spécifie la position où vous souhaitez que le bit. Si position==0, alors cette expression évaluer à:

    0000 0000 0000 0000 0000 0000 0000 0001 binary.

Si position==8, il évalue à

    0000 0000 0000 0000 0000 0001 0000 0000 binary.

en d'autres termes, il crée simplement un champ de 0 avec un 1 au niveau spécifié position. La seule partie délicate est dans la macro BitClr() où nous devons définir un simple 0 bit dans un champ de 1. Pour ce faire, on utilise les complément de la même expression que celle dénotée par l'opérateur tilde ( ~ ).

une Fois que le masque est créé, il est appliqué à l'argument, tout comme vous suggérer, par l'utilisation des opérateurs bitwise et (&), ou (|), et xor ( ^ ). Puisque le masque est de type long, les macros fonctionnent tout aussi bien sur le char, short, int, ou de long.

l'essentiel est qu'il s'agit d'une solution générale à une classe entière de problème. Il est, bien sûr, possible et même approprié de réécrire le équivalent de n'importe laquelle de ces macros avec des valeurs de masque explicites à chaque fois que vous besoin d'un, mais pourquoi faire? Rappelez-vous, la macro substitution se produit dans le préprocesseur et donc 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 à utiliser les macros généralisés comme "réinventer la roue" chaque fois que vous avez besoin de faire un peu de manipulation.

pas convaincu? Voici quelques codes de test-J'ai utilisé Watcom C avec une optimisation complète et sans utiliser _cdecl de sorte que 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.(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 18:07:16
la source

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

exemple:

value is 0x55;
bitnum : 3rd.

l'opérateur & est utilisé 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 Pivoter:

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)
29
répondu kapilddit 2015-05-22 19:09:54
la source

utilisez les opérateurs bitwise: & |

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 la représentation HEX, en fonction de la structure de données dans laquelle vous emballez des bits.

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

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

#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 dégager un peu:

BITOP(array, bit, &=~);

Pour basculer un peu:

BITOP(array, bit, ^=);

pour tester un bit:

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

etc.

24
répondu R.. 2013-05-09 18:21:00
la source

comme ceci est étiqueté "intégré", je suppose que vous utilisez un microcontrôleur. Toutes les suggestions ci-dessus sont valables & travail (lire-modifier-écrire, syndicats, structures, etc.).

cependant, au cours d'une période de débogage basé sur l'oscilloscope, j'ai été étonné de constater que ces méthodes ont une charge de travail considérable dans les cycles CPU par rapport à l'écriture d'une valeur directement sur les registres PORTnSET / PORTnCLEAR du micro, ce qui fait une réelle différence là où il y a des boucles serrées / les broches à bascule de l'ISR haute fréquence.

pour ceux qui ne sont pas familiers: dans mon exemple, le micro a un port général pin-state register qui reflète les pins de sortie, donc faire PORTn |= BIT_TO_SET se traduit par une lecture-modifier-écrire 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 "leave the pin alone". donc, vous vous retrouvez avec deux adresses de port selon que vous êtes le réglage ou le dégagement du bit (pas toujours commode) mais un beaucoup réaction plus rapide et plus petit code assemblé.

22
répondu John U 2012-06-14 19:23:17
la source

l'approche bitfield présente d'autres avantages dans l'arène intégrée. Vous pouvez définir une structure qui correspond directement aux bits dans 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'empaquetage de bits - je pense que C'est D'abord MSB, mais cela peut dépendre de la mise en œuvre. De plus, vérifiez comment vos gestionnaires de compilateurs passent les limites des octets.

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

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

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 11:38:21
la source

Check 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: Il est conçu pour être rapide (compte tenu de sa flexibilité) et sans ramification. Il en résulte un code machine SPARC efficace lors de la compilation de Sun Studio 8; Je l'ai également testé en utilisant MSVC++ 2008 sur amd64. Il est possible de créer des macros similaires pour régler et effacer les bits. La différence clé 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.

17
répondu John Zwinck 2009-01-04 02:44:14
la source

si vous faites beaucoup de peu de twiddling vous pourriez vouloir utiliser des masques qui feront le tout plus rapide. Les fonctions suivantes sont très rapides et sont encore souples (ils permettent peu tourner en peu de cartes 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;
}

Note, pour définir le bit 'n' Dans un entier de 16 bits vous faites ce qui suit:

TSetBit( n, &my_int);

c'est à vous de vous assurer que le nombre de bits se trouve à portée de la carte de bits que vous passez. Notez que pour les petits endian processeurs d'octets, de mots, dword, qwords, etc., map correctement à l'autre dans la mémoire (raison principale que les petits processeurs endian sont "mieux" que les processeurs big-endian, ah, je sens une guerre de flamme vient sur...).

13
répondu Tim Ring 2017-12-05 14:20:35
la source

ce programme est de changer n'importe quel bit de données de 0 à 1 ou 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 19:07:42
la source

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 19:06:03
la source

en expansion sur le bitset réponse:

#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 08:33:41
la source

si vous voulez effectuer tout cela avec la programmation C dans le noyau Linux alors je suggère d'utiliser les 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 déroule en une seule étape. Ainsi, ces Tous sont garantis d'être atomique même sur les ordinateurs SMP et sont utile pour maintenir la cohérence entre les processeurs.

9
répondu Jeegar Patel 2017-12-01 19:21:28
la source

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 la suppression 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;
    }
}

Note il n'y a rien de" spécial " dans ce code. Il traite un peu comme un entier - ce qui est techniquement le cas. Un entier de 1 bit qui peut contenir 2 valeurs, et 2 valeurs seulement.

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

8
répondu 2014-08-03 09:51:00
la source

utilisez l'un des opérateurs comme défini ici .

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

5
répondu Jason 2012-07-06 02:58:36
la source

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-07 02:11:18
la source

comment régler, effacer et basculer un seul bit?

pour répondre à un piège de codage commun lors de la tentative de 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 le poste 1 << x conduisant à un comportement indéfini (UB). Même si x n'est pas trop grand, ~ ne retournera peut-être pas 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-qui permet de coder/réviser/maintenir questions garder 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 au moins aussi large que le type de number .

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

comme avec la plupart des manipulations de bits, mieux de travailler avec non signé types plutôt que signé uns

3
répondu chux 2017-09-27 21:18:48
la source
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 15:35:12
la source

C++11 basées sur des modèles de version (mettez-les 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 23:51:05
la source

Variable utilisée

int value, pos;

valeur-Données

pos-position du bit que nous sommes intéressés à régler, effacer ou basculer

régler 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 20:32:56
la source

essayez l'une de ces fonctions dans le langage C pour changer N bit:

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 04:20:23
la source

Autres questions sur c++ c bitwise-operators bit-manipulation