2010-08-06 12 views
16

Im Moment habe ich das bin mit einstellen/ungesetzt einzelnen Bits in einem Byte:einfache Art und Weise zu setzen/ungesetzt ein einzelnes Bit

if (bit4Set) 
    nbyte |= (1 << 4); 
else 
    nbyte &= ~(1 << 4); 

Aber können Sie nicht tun, dass in einer einfacheren/elegant Weg? Wie setze oder schalte ich das Bit in einer einzigen Operation?

Hinweis: Ich verstehe, ich kann nur eine Funktion schreiben, um das zu tun, ich frage mich nur, ob ich nicht das Rad neu erfinden werde.

+4

http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c – obelix

+4

@obelix: So war SO also vor allem Die Fragen wurden schon beantwortet? + 112/+ 241, 90 Favs? Große Frage/Great Answer Gold Badge? –

Antwort

12

Sicher! Es wäre offensichtlich, wenn man die |= und &= im Code erweitert, aber Sie schreiben:

nbyte = (nbyte & ~(1<<4)) | (bit4Set<<4); 

Beachten Sie, dass bit4Set Null oder für diese ein -nicht jeder Nicht-Null-wert- sein müssen zu arbeiten.

+0

nicht gesetzt, dann abhängig von bit4set gesetzt. Daran habe ich nicht gedacht. Tks. – djeidot

+7

'nbyte = (nbyte & ~ (1 << 4)) | ((!! bit4Set) << 4) 'kümmert sich darum, dass bit4Set nicht null oder eins ist. –

11

Setzen Sie es in eine Funktion, der Bool-Typ erzwingt 0,1 für alle Bitval-Eingänge.

int change_bit(int val, int num, bool bitval) 
{ 
    return (val & ~(1<<num)) | (bitval << num); 
} 
+0

Wenn ich es in eine Funktion setze, würde ich lieber den Code verwenden, den ich geschrieben habe. Es ist trotzdem richtig. – djeidot

+5

Wenn Sie den Compiler diese Funktion in C++ inline einbinden lassen, dann ist es so schnell, als hätten Sie den Ausdruck selbst verwendet, und Sie erhalten den Lesbarkeitsbonus. –

0
nbyte |= (1 << 4); 

Wenn die rechte Seite der Zuweisung, (1 << 4), ist immer eine Konstante wie dieser, dann wäre dies wahrscheinlich durch den Compiler optimiert werden, so dass es einfacher in resultierende Anordnung wird:

mov r0, _nbyte 
mov r1, 10H   ; here is the optimization, no bit shift occured 
or r0, r1 
st _nbyte, r0 
+3

Dies ist die Antwort auf die Frage "Wie setze ich Bit 4 in nbyte?". Die Frage ist "Wie setze ich Bit 4 in nbyte je nach Wert von bit4Set?" –

+0

Danke. Ich habe die Frage missverstanden. Soll ich meine Antwort löschen? – Donotalo

6

Dies ist eine vollkommen sinnvolle und völlig Standardsprache.

+1

+1 Ich sehe dieses Idiom immer wieder im Mikrocontroller-Code. –

+0

Es _probably_ führt Verzweigungen ein, die die Leistung beeinträchtigen können.Pascal Cuoqs Antwort ist vielleicht weniger lesbar, aber leistungsfähiger. –

4

Haben Sie darüber nachgedacht, Ihren Bits Mnemonik und/oder Bezeichner zuzuweisen, statt sich auf die Zahlen zu beziehen?

Nehmen wir als Beispiel an, dass das Setzen von Bit 4 einen Kernreaktor SCRAM initiiert. Anstatt es als "Bit 4" zu bezeichnen, nennen wir es INITIATE_SCRAM. Hier ist, wie der Code für diese aussehen könnte:

int const INITIATE_SCRAM = 0x10; // 1 << 4 

... 

if (initiateScram) { 
    nbyte |= INITIATE_SCRAM; 
} else { 
    nbyte &= ~INITIATE_SCRAM; 
} 

Dies wird nicht unbedingt ein effiziente sein (nach der Optimierung) als Ihr ursprünglicher Code, aber es ist ein wenig klarer, glaube ich, und wahrscheinlich mehr wartbar.

+0

das ist ziemlich das Gleiche. Ich benutze tatsächlich Identifikatoren, ich habe sie einfach nicht in das Beispiel eingefügt. – djeidot

2

Dies ist als C++ markiert, also haben Sie in Betracht gezogen, std::bitset anstatt die ganze Bit-Manipulation selbst zu tun? Dann können Sie einfach Array-Notation verwenden wie: bits[3] = bit4Set, um das entsprechende Bit zu setzen.

Verwandte Themen