Frage

Wie tun Sie set, klar, und schalten Sie Sie ein bisschen in C/C++?

War es hilfreich?

Lösung

Ein bit gesetzt

Verwenden Sie den bitweisen or-operator (|), um ein bisschen.

number |= 1UL << n;

Das nth bisschen number. n sollte null sein, wenn Sie möchten, legen Sie die 1st bisschen und so weiter bis n-1, wenn Sie möchten, legen Sie die nth bit.

Verwenden 1ULL wenn number breiter als unsigned long;Förderung 1UL << n nicht der Fall, bis nach der Bewertung 1UL << n wo ist es Undefiniertes Verhalten Verschiebung um mehr als die Breite eines long.Das gleiche gilt für alle übrigen Beispiele.

Clearing ein bisschen

Verwenden Sie den bitweisen AND-operator (&) um ein bit.

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

Wird klar, dass die nth bisschen number.Sie müssen umkehren des bit-string mit der bitweise not-operator (~), dann UND es.

Mal ein bisschen

Der XOR-operator (^) kann verwendet werden, um etwas ändern.

number ^= 1UL << n;

Wird, schalten Sie die nth bisschen number.

Die überprüfung ein bisschen

Sie nicht Fragen, aber ich kann hinzufügen es.

Um zu überprüfen, etwas, verschieben die Zahl n auf der rechten Seite, dann bitweise UND:

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

Setzen, wird der Wert der nth bisschen number in die variable bit.

Ändern der nth bit zu x

Einstellung der nth bit zu entweder 1 oder 0 können erreicht werden mit die folgenden auf einem 2-Komplement C++ Implementierung:

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

Bit n wird gesetzt, wenn x ist 1, und deaktiviert, wenn x ist 0.Wenn x hat einen anderen Wert bekommen Sie Müll. x = !!x wird booleanize es auf 0 oder 1.

Um dies unabhängig von der 2-Komplement negation Verhalten (wo -1 alle bits gesetzt, anders als in einer 1-Komplement oder Vorzeichen/Größe C++ - Implementierung) verwenden Sie unsigned negation.

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

oder

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

Es ist generell eine gute Idee, um die Nutzung unsigned-Typen für portable bit-manipulation.

oder

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

(number & ~(1UL << n)) löschen Sie die nth bit-und (x << n) wird die nth bit zu x.

Es ist auch generell eine gute Idee, nicht zu kopieren/einfügen von code im Allgemeinen und so viele Menschen verwenden Präprozessor-Makros (wie die community-wiki-Antwort weiter unten) oder irgendeine Art von Kapselung.

Andere Tipps

Mit dem C++ - Standard-Bibliothek: std::bitset<N>.

Oder Boost version: boost::dynamic_bitset.

Es gibt keine Notwendigkeit, roll your own:

#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

Die Boost-version ermöglicht eine Laufzeit sized bitset im Vergleich zu einem standard-Bibliothek compile-Zeit, Größe bitset.

Die andere option ist die Verwendung von bit-Feldern:

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

struct bits mybits;

definiert einen 3-bit-Feld (eigentlich sind es drei 1-bit-felds).Bit-Operationen jetzt ein bisschen (haha) einfacher:

Zum setzen oder löschen Sie ein bisschen:

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

Zum Umschalten ein bisschen:

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

Die überprüfung ein wenig:

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

Dies funktioniert nur mit fester Größe-bit-Felder.Sonst, Sie haben zu resort zu die bit-twiddling beschriebenen Techniken in früheren posts.

Ich benutze Makros definiert in der header-Datei zu handhaben-bit gesetzt-und klar:

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

Manchmal ist es Wert, mit einem enum zu name bits:

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

Verwenden Sie dann die Namen später.I. e.schreiben

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

setzen, löschen und testen.Auf diese Weise haben Sie verbergen die Magische Zahl vom rest Ihres Codes.

Außer, dass ich zu eigen Jeremy Lösung.

Von 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, lassen Sie uns analysieren, Dinge...

Der gemeinsame Ausdruck, dass Sie zu sein scheinen Probleme mit der in allen von diesen ist "(1L << (posn))".All dies tut, ist erstellen Sie eine Maske, mit der ein einzelnes bit auf und die funktioniert mit jedem Datentyp "integer".Die "posn" - argument gibt die position, wo Sie wollen das bit.Wenn posn==0, dann wird der Ausdruck Bewertung zu:

0000 0000 0000 0000 0000 0000 0000 0001 binary.

Wenn posn==8, es wird ausgewertet:

0000 0000 0000 0000 0000 0001 0000 0000 binary.

Mit anderen Worten, es erzeugt einfach ein Feld von 0 mit einer 1 an der angegebenen position.Der einzige heikle Teil ist in der BitClr () - makro, wo wir brauchen, zu setzen ein 0-bit in einem Bereich von 1 ist.Dies wird erreicht, indem der 1 Ergänzung der gleiche Ausdruck, wie gekennzeichnet durch die tilde (~) operator.

Sobald die Maske wird erstellt, angewendet wird das argument nur,wie Sie vorschlagen, durch die Verwendung der bitweisen und (&), oder ( | ) und xor (^) Operatoren.Da die Maske ist vom Typ long, der Makros funktioniert genauso gut auf char ' s, kurz s, int, oder lang ist.

Die Quintessenz ist, dass dies ist eine Allgemeine Lösung für eine ganze Klasse von Probleme.Es ist natürlich möglich und sogar angebracht, umschreiben die entspricht eines dieser Makros mit ausdrücklicher Maske Werte jedes mal, wenn Sie ein brauchen, aber warum tun Sie es?Denken Sie daran, den makro-substitution tritt in der Präprozessor und so den generierten code wird die Tatsache widerspiegeln, dass die Werte werden als Konstante durch die compiler - d.h.es ist nur so effizient zu nutzen die generalisierte Makros, um "das Rad neu erfinden" zu jeder Zeit, die Sie brauchen, um zu tun bit-manipulation.

Nicht überzeugt?Hier einige test-code - ich habe Watcom C mit voller Optimierung und ohne mit _cdecl so dass die resultierende Demontage wäre so sauber wie möglich:

----[ 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.AUS (demontiert) ]-----------------------------------------------

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

Verwenden Sie die bitweisen Operatoren: & |

Setzen Letzte Stück in 000b:

foo = foo | 001b

Überprüfen Letzte Stück in foo:

if ( foo & 001b ) ....

Klar das Letzte Stück in foo:

foo = foo & 110b

Ich verwendet XXXb für Klarheit.Sie werden wahrscheinlich werden arbeiten mit der HEX-Darstellung, je nach Datenstruktur, in der du bist der Verpackung bits.

Für den Anfänger würde ich wie zu erklären, ein wenig mehr mit einem Beispiel:

Beispiel:

value is 0x55;
bitnum : 3rd.

Die & - operator wird verwendet, überprüfen 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)

Umschalten oder Flip:

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

| Betreiber:legen Sie die bit

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

Hier ist mein Lieblings-bit-Arithmetik-makro, das funktioniert für jede Art von unsigned-integer-array aus unsigned char bis zu size_t (welche ist die größte Typ, der sollte effizient sein, mit zu arbeiten):

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

Um ein bit:

BITOP(array, bit, |=);

Klar, ein bisschen:

BITOP(array, bit, &=~);

Zum Umschalten ein bisschen:

BITOP(array, bit, ^=);

Um zu testen, ein bisschen:

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

etc.

Das Bitfeld Ansatz hat andere Vorteile in der embedded-arena.Sie können definieren eine Struktur, die Karten direkt auf die bits in bestimmten hardware-register.

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;

Sie müssen sich bewusst sein, das bisschen Verpackung, um - ich denke, es ist MSB zuerst, doch kann dies von der Implementierung abhängig sein.Überprüfen Sie auch, wie Sie Ihre compiler-Handler Felder überqueren byte-Grenzen.

Sie können dann das Lesen, schreiben, testen Sie die einzelnen Werte wie vorher.

Als dieses gekennzeichnet ist "eingebettet" ich nehme an, Sie sind mit einem mikrocontroller.Alle obigen Hinweise gelten & work (read-modify-write, Gewerkschaften, Strukturen, etc.).

Jedoch, während ein Anfall von Oszilloskop-basierte debugging-ich war erstaunt zu finden, dass diese Methoden einen erheblichen Aufwand in der CPU-Zyklen im Vergleich zum schreiben ein Wert direkt an den micro PORTnSET / PORTnCLEAR registriert, die einen echten Unterschied macht, wo es tight loops / high-Frequenz ISR ' s Umschalten der pins.

Für diejenigen, die nicht:In meinem Beispiel, das Mikro hat eine Allgemeine pin-staatlichen register PORTn das spiegelt die output-pins, so tun PORTn |= BIT_TO_SET Ergebnisse in einem read-modify-write zu registrieren.Jedoch, die PORTnSET / PORTnCLEAR Register eine " 1 " zu bedeuten "bitte machen Sie das bit 1" (SET) oder "machen Sie bitte dieses bit null" (CLEAR) und eine " 0 " bedeutet "verlassen Sie die pin allein".also, Sie am Ende mit zwei-port-Adressen, je nachdem, ob Sie sind Einstellung bzw. deaktivieren Sie das bit (nicht immer bequem), aber eine viel schnellere Reaktion und kleineren zusammengesetzt code.

Mehr Allgemeine, für beliebig große bitmaps:

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

Schauen Sie ein wenig an eine beliebige Position in einer Variablen beliebigen Typs:

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

Ein Beispiel für die Verwendung:

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

Hinweise: Diese ist entwickelt, um schnell (aufgrund seiner Flexibilität) und nicht-weitverzweigt.Es ergibt sich in effiziente SPARC-Maschinen-code kompiliert, wenn Sun Studio 8;Ich habe auch getestet mit MSVC++ 2008 auf amd64.Es ist möglich zu machen, ähnlich wie Makros zum einstellen und löschen von bits.Der wesentliche Unterschied dieser Lösung im Vergleich zu vielen anderen hier, ist, dass es funktioniert, für jeden Ort in so ziemlich jede Art von variable.

Dieses Programm jede änderung an den Daten-bit von 0 auf 1 oder 1 auf 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);
        }
    }
}

Wenn Sie tun eine Menge der bit-twiddling, die Sie möchten möglicherweise verwenden Sie Masken, die machen die ganze Sache schneller.Die folgenden Funktionen sind sehr schnell und sind immer noch flexibel (Sie erlauben die bit-twiddling in bit-Karten beliebiger Größe).

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

Hinweis zu bit 'n' in eine 16-bit-Ganzzahl, die Sie tun, die folgenden:

TSetBit( n, &my_int);

Es ist bis zu Ihnen, um sicherzustellen, dass die bit-Anzahl ist im Bereich der bit-map, die Sie übergeben.Beachten Sie, dass für little-endian-Prozessoren, bytes, words, dwords, qwords, etc., Karte korrekt zueinander im Speicher (Haupt-Grund, dass die little-endian-Prozessoren sind "besser" als big-endian-Prozessoren, ah, ich fühle eine Flamme, Krieg kommen auf...).

Benutzen Sie diese:

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

    return num;
}

Die Erweiterung auf die bitset Antwort:

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

Wenn Sie möchten, führen Sie diesen Betrieb mit C-Programmierung in der Linux-kernel dann schlage ich vor, die Verwendung von standard-APIs des Linux-Kernels.

Finden 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

Hinweis:Hier der gesamte Vorgang geschieht in einem einzigen Schritt.Also alle diese sind garantiert zu werden atomic auch auf SMP-Computer und nützlich sind zu halten, die Kohärenz über Prozessoren.

Visual C 2010, und vielleicht viele andere Compiler haben direkte Unterstützung für bit-Operationen gebaut.Überraschenderweise funktioniert dies, auch die sizeof() operator funktioniert.

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

So, zu deiner Frage, IsGph[i] =1, oder IsGph[i] =0 machen Einstellung und Reinigung bools einfach.

Zu finden, die nicht druckbare Zeichen:

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

Hinweis es ist nichts "besonderes" über diesen code.Es behandelt ein bisschen wie eine Ganzzahl, die technisch gesehen ist es.Ein 1-bit-Ganzzahl, die halten kann die 2 Werte, und 2 Werte nur.

Ich habe mal nach diesem Ansatz zum Auffinden von doppelten Darlehen records, wo loan_number war die ISAM-Schlüssel, verwenden die 6-stellige Kredit-Nummer als index in das bit-array.Brutal schnell, und nach 8 Monaten, bewiesen, dass der mainframe-system, das wir immer waren die Daten von in der Tat war fehlerhaft.Die Einfachheit des bit-arrays macht, Vertrauen in Ihre Richtigkeit sehr hoch - vs, die die Suche nach Vorgehensweise zum Beispiel.

Einer der Operatoren definiert hier.

Um ein bit, verwendet int x = x | 0x?; wo ? ist die bit-position in binärer form.

Hier sind einige Makros, die ich benutze:

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)

Variabel einsetzbar

int value, pos;

Wert - Daten
pos - position des Bits, das wir sind daran interessiert zu setzen, deaktivieren oder Umschalten.

Ein bit:

value = value | 1 << pos;

Klar, ein bisschen:

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

Etwas ändern:

value = value ^ 1 << pos;

Wie tun Sie setzen, entfernen, und Umschalten, ein einzelnes bit?

Adresse, einen gemeinsamen coding-Fehler beim Versuch, die form der Maske:
1 nicht immer ist breit genug

Welche Probleme passieren, wenn number ist eine größere Art als 1?
x möglicherweise zu groß für die Verschiebung 1 << x führenden zu Undefiniertes Verhalten (UB).Auch wenn x nicht zu groß, ~ kann nicht flip genug, most-significant-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

Versichern 1 ist breit genug:

Code verwenden könnte 1ull oder pedantisch (uintmax_t)1 und lassen Sie den compiler optimieren.

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

Oder gegossen - das macht für die Codierung/review/Instandhaltung halten Sie die-cast richtige und up-to-date.

number |= (type_of_number)1 << x;

Oder sanft fördern die 1 erzwingen Sie eine mathematische operation, die ist mindestens so breit wie die Art der number.

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

Wie bei den meisten bit-Manipulationen, beste zu arbeiten mit unsigned sondern Typen signiert diejenigen

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

Ein C++11-Vorlagen-version (in header):

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

Versuchen Sie eine dieser Funktionen in der C-Sprache zu ändern n bit:

char bitfield;

// Start at 0th position

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

Oder

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

Oder

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top