Como você define, desimpede e comuta um único pedaço?

como é que se define, desimpede e comuta um pouco em C/C++?

Author: WaleedYaser, 2008-09-07

26 answers

Ajustar um pouco

Use o bitwise ou operador (|) para definir um pouco.

number |= 1UL << n;

Isso irá definir a na segunda parte de number.

Usar 1ULL Se number for mais largo que unsigned long; a promoção de 1UL << n não acontece até depois de avaliar 1UL << n onde o comportamento não definido muda em mais do que a largura de um long. O mesmo se aplica a todos os outros exemplos.

A limpar um pouco

Utilize o bitwise e o operador (&) para limpar a pouco.

number &= ~(1UL << n);
Isso vai limpar a parte de n. Você deve inverter a cadeia de bits com o operador bitwise não (~), Então E ele.

Comutando um pouco

O operador XOR (^) pode ser usado para comutar um pouco.

number ^= 1UL << n;

Isso irá comutar a nésima parte de number.

A verificar um pouco

Não pediste isto, mas mais vale adicioná-lo.

Para verificar um pouco, mude o número n para a direita, em seguida bitwise e it:

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

Isso irá colocar o valor do nbit de number na variável bit.

Mudar oN para x

A configuração do n para 1 ou 0 pode ser alcançada com o seguinte no complemento de 2 implementação em C++:

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

O Bit n será definido se x for 1, e limpo se x for 0. Se x tem algum outro valor, você obtém lixo. {[35] } vai booleanizá-lo para 0 ou 1.

Para tornar isto independente do comportamento de negação do complemento de 2 (em que -1 tem todos os bits definidos, ao contrário do complemento de um 1 ou da implementação de sinal/magnitude C++), use a negação sem sinal.

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

Ou

unsigned long newbit = !!x;    // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
Geralmente é uma boa ideia usar tipos sem sinal para manipulação de bits portáteis. Também é geralmente uma boa ideia não copiar / colar o código em geral e muitas pessoas usam macros pré-processadores (como a comunidade wiki responde ainda mais ou algum tipo de encapsulação.
 3077
Author: Jeremy Ruten, 2018-07-24 18:42:18

Usando a biblioteca C++ Padrão: std::bitset<N>.

Ou oimpulso Versão: boost::dynamic_bitset.

Não há necessidade de rolar o seu próprio:
#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

A versão Boost permite um conjunto de bits do tamanho de execução em comparação com uma biblioteca padrão .

 392
Author: Martin York, 2018-02-16 01:18:57

A outra opção é usar campos de bits:

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

struct bits mybits;

Define um campo de 3 bits (na verdade, são três felds de 1 bits). Operações Bit agora se tornam um pouco (haha) mais simples:

Para definir ou limpar um pouco:

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

To toggle a bit:

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

A verificar um pouco:

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

Isto só funciona com campos de bits de tamanho fixo. Caso contrário, você tem que recorrer às técnicas de bit-twiddling descritas em posts anteriores.

 216
Author: Ferruccio, 2012-11-29 00:40:32

Eu uso macros definidas num ficheiro de cabeçalho para lidar com o conjunto de bits e limpar:

/* 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
Author: Steve Karg, 2017-11-10 21:30:17

Às vezes vale a pena usar um nome enum a Os bits:

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

Depois usa os nomes . Ou seja, escrever

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

Preparar, limpar e testar. Assim escondes os números mágicos do resto do teu código.

Tirando isso, apoio a solução do Jeremy.
 101
Author: dmckee, 2013-10-18 15:54:21

De 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)))
Muito bem, vamos analisar as coisas...

A expressão comum com a qual você parece estar tendo problemas em tudo isso é "(1L

    0000 0000 0000 0000 0000 0000 0000 0001 binary.

Se posn = 8, irá avaliar a

    0000 0000 0000 0000 0000 0001 0000 0000 binary.

Em outras palavras, simplesmente cria um campo de 0's com um 1 No especificado posicao. A única parte complicada é na macro BitClr() onde precisamos definir um único 0 bit em um campo de 1's. isto é conseguido usando o 1's complemento da mesma expressão denotada pelo operador tilde ( ~ ).

Uma vez criada a máscara, é aplicada ao argumento tal como sugere., pelo uso dos operadores bitwise e (&), ou (|), e xor ( ^ ). Desde a máscara é de Tipo Longo, as macros funcionarão assim como no char's, short's, int's, ou long's. A conclusão é que esta é uma solução geral para toda uma classe de problema. É claro que é possível e até apropriado reescrever o equivalente a qualquer uma destas macros com valores de máscara explícitos cada vez que você preciso de um, mas porquê? Lembre-se, a substituição macro ocorre no pré-processador e assim o código gerado refletirá o fato de que os valores são considerados constantes pelo compilador-isto é, é apenas como eficiente de usar as macros generalizadas quanto a "reinventar a roda" cada vez que você precisa fazer manipulação de bits. Não convencido? Aqui está um código de teste - eu usei Watcom C com otimização completa e sem usar _decl de modo que a desmontagem resultante seria tão limpa como possível:

----[ teste.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;
}

----[ teste.Fora (desmontado) ]-----------------------------------------------

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
Author: yogeesh, 2018-03-07 15:07:16
Para o principiante, gostaria de explicar um pouco mais com um exemplo:

Exemplo:

value is 0x55;
bitnum : 3rd.

O operador & é usado verifique o 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)

Alternar ou inverter:

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

| operador: definir o bit

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

Utilize os operadores bitwise: & |

Para definir a última parte em 000b:

foo = foo | 001b

Para verificar a última parte em foo:

if ( foo & 001b ) ....
Para limpar a última parte foo:
foo = foo & 110b

Usei {[8] } para clareza. Você provavelmente estará trabalhando com representação HEX, dependendo da estrutura de dados em que você está empacotando bits.

 28
Author: nsanders, 2018-04-12 11:23:14

Aqui está a minha macro aritmética de bits favorita, que funciona para qualquer tipo de conjunto inteiro sem sinal de unsigned char até size_t (que é o maior tipo que deve ser eficiente de trabalhar):

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

Para definir um pouco:

BITOP(array, bit, |=);

Para limpar um pouco:

BITOP(array, bit, &=~);

To toggle a bit:

BITOP(array, bit, ^=);

Para testar um pouco:

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

Etc.

 24
Author: R.., 2013-05-09 14:21:00
Como isto está marcado "embutido", presumo que esteja a usar um microcontrolador. Todas as sugestões acima são válidas & trabalho (read-modify-write, sindicatos, estruturas, etc.).

No Entanto, durante um ataque de osciloscópio baseado depuração eu estava surpreso ao descobrir que estes métodos têm uma sobrecarga considerável em ciclos de CPU em relação a escrita de um valor diretamente para o micro PORTnSET / PORTnCLEAR registra o que faz uma diferença real onde há justo ciclos / alta frequência ISR da alternância PIM.

Para aqueles que não estão familiarizados: no meu exemplo, o micro tem uma porta Geral de Registo pin-state que reflecte os pinos de saída, pelo que ao fazer PORTn |= BIT_TO_SET resulta num read-modify-write para esse registo. No entanto, os registradores PORTnSET / PORTnCLEAR tomam um '1' para significar "por favor, faça este bit 1" (SET) ou "por favor faça este bit zero" (CLEAR) e um '0' para significar "deixe o pin em paz". então, você acaba com dois endereços de portas dependendo se você está configurando ou limpando o bit (nem sempre conveniente) mas um Muito uma reacção mais rápida e um código menor montado.

 22
Author: John U, 2012-06-14 15:23:17
A abordagem bitfield tem outras vantagens na arena incorporada. Você pode definir uma estrutura que mapeia diretamente para os bits em um registro de hardware particular.
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;

Você precisa estar ciente da ordem de empacotamento de bits-eu acho que é MSB primeiro, mas isso pode ser implementação-dependente. Além disso, verifique como os seus tratadores de compiladores cruzam os limites do byte.

Você pode então ler, escrever, testar os valores individuais como antes.

 21
Author: Roddy, 2008-11-06 11:30:16
Mais geral, para bitmaps de tamanho arbitrário:
#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
Author: bill, 2009-06-15 07:38:21

Verifique um pouco num local arbitrário numa variável de tipo arbitrário:

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

Utilização da amostra:

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

Notas: Esta é projetada para ser rápida (dada a sua flexibilidade) e não-ramificada. Ele resulta em um código de máquina SPARC eficiente quando compilado Sun Studio 8; eu também testei usando MSVC++ 2008 em amd64. É possível fazer macros semelhantes para definir e limpar bits. A principal diferença desta solução em comparação com muitas outras aqui é que funciona para qualquer localização em praticamente qualquer tipo de variável.

 17
Author: John Zwinck, 2009-01-03 23:44:14
Se você está fazendo um monte de rodopios você pode querer usar máscaras que vão tornar tudo mais rápido. As seguintes funções são muito rápidas e ainda flexíveis (elas permitem twiddling bit em mapas bit de qualquer tamanho).
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: para definir o bit ' n ' num número inteiro de 16 bits, faz o seguinte:

TSetBit( n, &my_int);

Cabe a você garantir que o número de bits está dentro do intervalo do mapa de bits que você passa. Note que para pequenos processadores endianos que bytes, palavras, dwords, qwords, etc., map correctly to each other in memory (main reason that little endian processors are 'better' than big-endian processors, ah, I feel a flame war coming on...).

 13
Author: Tim Ring, 2017-12-05 11:20:35

Este programa é para alterar qualquer bit de dados de 0 para 1 ou 1 para 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
Author: Gokul Naathan, 2015-05-22 16:07:42

Usa isto:

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

    return num;
}
 11
Author: Peter Mortensen, 2015-05-22 16:06:03

Expandindo a resposta 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
Author: kendotwill, 2014-05-08 04:33:41

Se quiser executar esta operação toda com a programação C no kernel Linux , sugiro que use APIs-padrão do kernel Linux.

Ver 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: aqui toda a operação acontece em um único passo. Então, todos estes são garantidos para ser atômico mesmo em computadores SMP e são úteis manter a coerência entre os processadores.
 9
Author: Jeegar Patel, 2017-12-01 16:21:28

Visual C 2010, e talvez muitos outros compiladores, têm suporte direto para operações de bits incorporadas. Surpreendentemente, isso funciona, mesmo o tamanho do () operador funciona corretamente.

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);
}
Então, para sua pergunta, IsGph [i] =1, ou IsGph[i] =0 tornar a configuração e a limpeza de bóia fácil.

Para encontrar caracteres intratáveis...

//  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 que não há nada de especial neste código. Trata um pouco como um inteiro - o que tecnicamente, é. Um inteiro de 1 bit que pode conter 2 valores, e apenas dois valores.

Uma vez usei esta abordagem para encontrar registos de empréstimos duplicados, onde o número de empréstimos era a chave ISAM, usando o número de empréstimos de 6 dígitos como um índice na lista de bits. Selvagemente rápido, e depois de 8 meses, provou que o sistema principal do qual estávamos recebendo os dados estava de fato funcionando mal. A simplicidade de matrizes de bits faz a confiança em sua correção muito alta - vs uma abordagem de busca, por exemplo.

 8
Author: , 2014-08-03 05:51:00

Utilize um dos operadores definidos aqui.

Para definir um bit, usado int x = x | 0x?; onde ? é a posição dos bit na forma binária.

 5
Author: Jason, 2012-07-05 22:58:36

Aqui estão algumas macros que eu 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)
 4
Author: sam msft, 2015-02-06 23:11:18

Como é que se define, desimpede e comuta um bocadinho?

Para abordar uma falha de codificação comum ao tentar formar a máscara:
1 nem sempre é suficientemente largo

Que problemas acontecem quando number é um tipo mais largo do que 1?
x pode ser muito grande para a mudança 1 << x levando a comportamento indefinido (UB). Mesmo que x não seja muito grande, ~ pode não virar bastante bits mais significativos.

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

Para seguro 1 é largo o suficiente:

O código pode usar {[11] } ou pedanticamente (uintmax_t)1 e deixar o compilador optimizar.

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

Ou cast - O que torna as questões de codificação/revisão/manutenção correctas e actualizadas.

number |= (type_of_number)1 << x;

Ou promover gentilmente o 1 forçando uma operação matemática que é tão pequena quanto o tipo de number.

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

Tal como acontece com a maioria das manipulações de bits, é melhor trabalhar com tipos não assinados em vez de assinados uns

 3
Author: 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
Author: Sazzad Hissain Khan, 2018-02-21 12:35:12

Uma versão templada C++11 (colocar num cabeçalho):

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
Author: Joakim L. Christiansen, 2018-02-27 20:51:05

Variável utilizada

int value, pos;

Value-Data
pos-posição do bit que estamos interessados em Definir, limpar ou comutar
definir um pouco

value = value | 1 << pos;

Limpar um pouco

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

Comutar um pouco

value = value ^ 1 << pos;
 2
Author: Jeet Parikh, 2018-07-11 17:32:56

Tente uma destas funções na linguagem C para mudar 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
Author: Vincet, 2018-02-16 01:20:23