Domanda

Come si fa a impostare, chiaro, e passare un po ' in C/C++?

È stato utile?

Soluzione

L'impostazione di un bit

Utilizzare l'operatore or bit a bit (|) per impostare un po'.

number |= 1UL << n;

Che consente di impostare il nth po ' di number. n dovrebbe essere pari a zero, se si desidera impostare il 1st bit e così via fino a n-1, se si desidera impostare il nth po'.

Utilizzare 1ULL se number è più ampia rispetto a unsigned long;promozione di 1UL << n non accadrà fino a dopo la valutazione 1UL << n dove è definito il comportamento di spostare di più rispetto alla larghezza di una long.Lo stesso vale per tutti il resto degli esempi.

Rimozione di un po'

Utilizzare l'operatore and bit a bit (&) per cancellare un po'.

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

Che sarà chiaro il nth po ' di number.È necessario invertire la stringa di bit con bit a bit operatore NOT (~), E poi farlo.

La commutazione di un po'

L'operatore XOR (^) può essere utilizzato per cambiare un po'.

number ^= 1UL << n;

Che farà passare il nth po ' di number.

Controllando un po'

Non avete chiesto questo, ma potrei anche aggiungere.

Per controllare un po', sposta il numero n di destra, poi a livello di bit E:

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

Mettere il valore della nth po ' di number nella variabile bit.

Cambiando il nth po ' di x

Impostazione del nth po ' per uno 1 o 0 può essere raggiunto con il seguente complemento a 2 implementazione di C++:

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

Bit n verrà impostato se x è 1, e se deselezionata x è 0.Se x ha un altro valore, si ottiene spazzatura. x = !!x sarà booleanize a 0 o 1.

Per fare questo indipendente di 2 complemento di negazione del comportamento (dove -1 ha tutti i bit impostati, a differenza di un complemento a 1 o segno/grandezza implementazione di C++), uso senza segno di negazione.

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

o

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

E ' generalmente una buona idea di utilizzare i tipi senza segno per portatili di manipolazione dei bit.

o

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

(number & ~(1UL << n)) sarà chiaro il nth po ' e (x << n) imposta il nth po ' di x.

E ' generalmente una buona idea di non copiare/incollare il codice in generale, e così molte persone usano macro del preprocessore (come la comunità wiki risposta più in basso) o un qualche tipo di incapsulamento.

Altri suggerimenti

Utilizzando la Libreria Standard di C++: std::bitset<N>.

O il Boost versione: boost::dynamic_bitset.

Non c'è bisogno di rotolare il vostro proprio:

#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

Il Boost versione permette l'esecuzione di dimensioni bitset rispetto a un la libreria standard in fase di compilazione di dimensioni bitset.

L'altra opzione è quella di utilizzare i campi di bit:

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

struct bits mybits;

definisce un 3-campo di bit (in realtà, è 1 po ' felds).Operazioni sui Bit, ora è diventata un po ' (ride) più semplice:

Per impostare o cancellare un po':

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

Per cambiare un po':

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

Controllando un po':

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

Questo funziona solo con dimensioni fisse di campi di bit.Altrimenti devi ricorrere alla bit-giocherellando tecniche descritte nel post precedente.

Io uso le macro definite in un file di intestazione per gestire set di bit e chiaro:

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

È a volte vale la pena enum per nome i bit:

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

Quindi utilizzare il nomi in seguito.I. e.scrivere

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

per impostare, chiaro e test.In questo modo si nasconde la magia dei numeri dal resto del codice.

Diverso da quello che mi approva Jeremy soluzione.

Da 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, vediamo di analizzare le cose...

L'espressione comune che ti sembra di avere problemi con in tutto "(1L << (pos))".Tutto questo non fa altro che creare una maschera con un singolo bit su e che funzionerà con qualsiasi tipo integer.Il "pos" argomento specifica il la posizione in cui si desidera che il bit.Se pos==0, quindi questa espressione valutare a:

0000 0000 0000 0000 0000 0000 0000 0001 binary.

Se pos==8, valuterà, a:

0000 0000 0000 0000 0000 0001 0000 0000 binary.

In altre parole, si crea semplicemente un campo di 0 con un 1 a specificato posizione.L'unica parte difficile è in BitClr() macro in cui abbiamo bisogno di impostare un singolo bit 0 in un campo di 1.Questo avviene tramite l'1 complemento della stessa espressione, come recita la tilde (~) per l'operatore.

Una volta che viene creata la maschera, a cui viene applicata l'argomento proprio come suggerisci tu, da utilizzare l'operatore and (&), or (|), xor (^) gli operatori.Dato che la maschera è di tipo long, la macro funziona altrettanto bene su char, short, int, o long.

La linea di fondo è che questa è una soluzione generale di un'intera classe di problemi.È possibile, naturalmente, e anche opportuno riscrivere la equivalente di una qualsiasi di queste macro con esplicita i valori della maschera ogni volta che si bisogno, ma perché farlo?Ricordate, la sostituzione di macro si verifica nel il preprocessore e così il codice generato in considerazione del fatto che i valori sono considerati costante dal compilatore - cioèè efficiente la generalizzata macro di "reinventare la ruota" ogni volta che avete bisogno di fare la manipolazione dei bit.

Non convinto?Ecco alcuni test di codice che ho usato Watcom C con l'ottimizzazione completa e senza l'utilizzo di _cdecl quindi il conseguente smontaggio sarebbe più pulito possibile:

----[ 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 (smontato) ]-----------------------------------------------

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 ]-----------------------------------------------------------------

Utilizzare gli operatori bit a bit: & |

Per impostare ultimo bit in 000b:

foo = foo | 001b

Per controllare l'ultimo bit foo:

if ( foo & 001b ) ....

Per cancellare ultimo bit in foo:

foo = foo & 110b

Ho usato XXXb per maggiore chiarezza.Probabilmente lavorare con la rappresentazione ESADECIMALE, a seconda della struttura dati in cui sei imballaggio bit.

Per il principiante, vorrei spiegare un po ' di più con un esempio:

Esempio:

value is 0x55;
bitnum : 3rd.

Il & operatore di controllare il 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)

Toggle o Flip:

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

| operatore:impostare il bit

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

Ecco la mia preferita po ' di aritmetica macro, che funziona per qualsiasi tipo di unsigned integer array unsigned char fino a size_t (che è il tipo più grande che dovrebbe essere efficiente di lavorare con):

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

Per impostare un po':

BITOP(array, bit, |=);

Per cancellare un po':

BITOP(array, bit, &=~);

Per cambiare un po':

BITOP(array, bit, ^=);

Per testare un po':

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

ecc.

Il campo di bit approccio ha altri vantaggi incorporato arena.È possibile definire una struct che le mappe direttamente sul bit in un particolare registro hardware.

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;

È necessario essere consapevoli del bit ordine di imballaggio, penso sia MSB, ma questo può essere dipendente dall'implementazione.Inoltre, è possibile verificare come il compilatore gestori di campi attraversamento limiti di byte.

Quindi è possibile leggere, scrivere, testare i singoli valori come prima.

Questo è tagged "embedded" si assume che si sta utilizzando un microcontrollore.Tutti i suggerimenti sopra riportati sono validi & lavoro (read-modify-write, sindacati, strutture, etc.).

Tuttavia, durante un incontro con l'oscilloscopio a base di debug sono stato stupito di scoprire che questi metodi hanno un notevole sovraccarico in cicli di CPU rispetto alla scrittura di un valore direttamente al micro PORTnSET / PORTnCLEAR registri che fa veramente la differenza, dove ci sono loop / ad alta frequenza ISR commutazione pin.

Per chi non conoscesse:Nel mio esempio, il micro ha un generale pin-registro di stato PORTn che riflette il pin di uscita, in modo da fare PORTn |= BIT_TO_SET risultati in un read-modify-write per il registro.Tuttavia, il PORTnSET / PORTnCLEAR registri di prendere un '1' per dire "si prega di fare questo bit 1" (SET) o "si prega di prendere questo bit zero" (CHIARA) e un '0' significa "lasciare il pin da solo".così, si finisce con due indirizzi di porta a seconda se si sta selezionando o deselezionando la bit (non sempre facile), ma un molto di reazione più veloci e più piccoli assemblato.

Più in generale, per arbitrario di dimensioni bitmap:

#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)))

Controllare un po ' in una posizione arbitraria in una variabile di tipo arbitrario:

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

Un esempio di utilizzo:

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

Note: Questo è stato progettato per essere veloce (data la sua flessibilità) e non ramoso.Risultati efficiente SPARC codice macchina quando viene compilato Sun Studio 8;Ho testato anche utilizzando MSVC++ 2008 su amd64.È possibile fare un simile macro per impostare e cancellare bit.La differenza principale di questa soluzione rispetto a molti altri qui è che funziona per qualsiasi posizione in praticamente qualsiasi tipo di variabile.

Questo programma è quello di cambiare i dati di bit da 0 a 1 o da 1 a 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);
        }
    }
}

Se stai facendo un sacco di po ' con le mani in mano si potrebbe desiderare di utilizzare le maschere che rendono il tutto più veloce.Le seguenti funzioni sono molto veloci e sono ancora flessibili (consentono po ' con le mani in mano in mappe di bit di qualsiasi dimensione).

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

Nota per impostare il bit 'n' in un numero intero a 16 bit si effettuano le seguenti operazioni:

TSetBit( n, &my_int);

Spetta a voi per assicurarsi che il numero di bit è all'interno della gamma della mappa di bit che si passa.Nota che per little endian processori di byte, parole, parole, qwords, ecc.... mappa correttamente a ogni altro in memoria (principale motivo che little endian processori sono migliori rispetto a big-endian processori, ah, mi sento una guerra fiamma venuta via...).

Uso questo:

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

    return num;
}

L'espansione di bitset risposta:

#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;
}

Se si desidera eseguire questo operazione con la programmazione C in Linux kernel quindi io suggerisco di usare le Api del kernel di Linux.

Vedere 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

Nota:Qui l'intera operazione avviene in un unico passaggio.Quindi, tutti questi sono garantiti per essere atomic anche su computer SMP e sono utili per mantenere la coerenza tra i processori.

Visual C 2010, e forse molti altri compilatori, avere il supporto diretto per le operazioni sui bit integrato.Sorprendentemente, questo funziona, anche il sizeof() operatore funziona correttamente.

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);
}

Così, per la tua domanda, IsGph[i] =1, o IsGph[i] =0 fare l'impostazione e cancellazione di bools facile.

Per trovare i caratteri non stampabili:

//  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;
    }
}

Nota non c'è niente di "speciale" su questo codice.Si tratta un po ' come un numero intero che tecnicamente è.A 1 bit che può contenere 2 valori, e 2 valori.

Una volta ho usato questo approccio per trovare duplicati di prestito record, dove loan_number era l'ISAM chiave, utilizzando le 6 cifre del prestito numero come indice nella matrice di bit.Selvaggiamente veloce, e dopo 8 mesi, ha dimostrato che il sistema mainframe siamo riusciti ad ottenere i dati è in realtà funziona correttamente.La semplicità di matrici di bit rende la fiducia nella loro esattezza molto alta rispetto a un approccio alla ricerca, per esempio.

Utilizzare uno degli operatori come definito qui.

Per impostare un po', usato int x = x | 0x?; dove ? è la posizione del bit in forma binaria.

Qui ci sono alcune macro che uso:

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)

Variabile utilizzata

int value, pos;

valore Dati
pos - posizione del bit che a noi interessano per impostare, eliminare o passare.

Impostare un po':

value = value | 1 << pos;

Chiaro un po':

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

Passare un po':

value = value ^ 1 << pos;

Come si fa a impostare, eliminare e cambiare un singolo bit?

Per affrontare una codifica comune insidia quando tenta di formare la maschera:
1 non è sempre abbastanza ampia

Quali sono i problemi accadere quando number è una più ampia tipologia di 1?
x potrebbe essere troppo grande per il turno 1 << x leader per un comportamento indefinito (UB).Anche se x non è troppo grande, ~ non possono girare abbastanza più significativo-bit.

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

Per assicurare la 1 è abbastanza ampia:

Codice potrebbe utilizzare 1ull o pedantemente (uintmax_t)1 e lasciare che il compilatore ottimizza.

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

O cast, il che rende per la codifica/revisione/manutenzione questioni talmente semplice mantenere aggiornati i cast corretto e aggiornato.

number |= (type_of_number)1 << x;

O delicatamente promuovere la 1 forzando un operazione matematica che è almeno altrettanto vasta come il tipo di number.

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

Come con la maggior parte dei bit manipolazioni, meglio lavorare con unsigned tipi piuttosto che firmato quelli

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);
}

C++11 basati su modello versione (inserire una intestazione):

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

Provare una di queste funzioni in linguaggio C per cambiare n bit:

char bitfield;

// Start at 0th position

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

O

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

O

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top