Ändern Sie ein bisschen eine ganze Zahl [duplicate]

Lesezeit: 2 Minuten

Benutzeravatar von pedram
pedram

Wir haben eine ganze Zahl

int x = 50;

in binär ist es

00110010

Wie kann ich das vierte (4.) Bit programmatisch ändern?

Benutzeravatar von templatetypedef
Vorlagentypdef

Sie können das vierte Bit einer Zahl setzen, indem Sie es mit einem Wert ODER-verknüpfen, der überall außer im vierten Bit Null ist. Dies könnte so erfolgen

x |= (1u << 3);

Auf ähnliche Weise können Sie das vierte Bit löschen, indem Sie es mit einem Wert UND-verknüpfen, der überall außer im vierten Bit Eins ist. Zum Beispiel:

x &= ~(1u << 3);

Schließlich können Sie das vierte Bit durch XOR-Verknüpfung mit einem Wert umschalten, der überall außer im vierten Bit Null ist:

x ^= (1u << 3);

Um zu sehen, warum das funktioniert, müssen wir uns zwei Dinge ansehen:

  1. Wie ist das Verhalten der << Betreiber in diesem Zusammenhang?
  2. Wie verhalten sich hier die Operatoren AND, OR und XOR?

In allen drei der obigen Codeausschnitte haben wir die << Operator, um einen Wert zu generieren. Das << Der Operator ist der bitweise Verschiebungsoperator, der einen Wert annimmt und dann alle seine Bits um einige Schritte nach links verschiebt. In Ihrem Fall habe ich verwendet

1u << 3

den Wert 1 zu nehmen (der die binäre Darstellung 1 hat) und dann alle seine Bits um drei Punkte zu verschieben, wobei die fehlenden Werte mit 0 ausgefüllt werden. Dadurch entsteht der binäre Wert 1000bei dem im vierten Bit ein Bit gesetzt ist.

Nun, warum tut

x |= (1u << 3);

das vierte Bit der Zahl setzen? Das hat mit der Funktionsweise des ODER-Operators zu tun. Das |= Betreiber ist wie += oder *= außer bitweisem ODER – es ist äquivalent zu

x = x | (1u << 3);

Warum also OR-ing x mit dem binären Wert 1000 sein viertes Bit setzen? Dies hat mit der Art und Weise zu tun, wie OR definiert ist:

0 | 0  == 0
0 | 1  == 1
1 | 0  == 1
1 | 1  == 1

Noch wichtiger ist jedoch, dass wir dies kompakter umschreiben können als

x | 0  == x
x | 1  == 1

Dies ist eine äußerst wichtige Tatsache, da es bedeutet, dass die ODER-Verknüpfung eines beliebigen Bits mit Null den Wert des Bits nicht ändert, während die ODER-Verknüpfung eines beliebigen Bits mit 1 dieses Bit immer auf Eins setzt. Das heißt, wenn wir schreiben

x |= (1u << 3);

Da (1u << 3) ein Wert ist, der überall außer im vierten Bit Null ist, lässt das bitweise ODER alle Bits von x unverändert, mit Ausnahme des vierten Bits, das dann auf Eins gesetzt wird. Allgemeiner wird das ODER-Verknüpfen einer Zahl mit einem Wert, der eine Reihe von Nullen und Einsen ist, alle Werte bewahren, bei denen die Bits Null sind, und alle Werte setzen, bei denen die Bits Eins sind.

Schauen wir uns nun an

x &= ~(1u << 3);

Dies verwendet den bitweisen Komplementoperator ~, die eine Zahl nimmt und alle ihre Bits umdreht. Wenn wir davon ausgehen, dass Ganzzahlen zwei Bytes sind (nur der Einfachheit halber), bedeutet dies, dass die tatsächliche Codierung von (1u << 3) ist

0000000000001000

Wenn wir davon das Komplement bilden, erhalten wir die Zahl

1111111111110111

Sehen wir uns nun an, was passiert, wenn wir bitweise UND zwei Werte miteinander verknüpfen. Der UND-Operator hat diese interessante Wahrheitstabelle:

0 & 0   == 0
0 & 1   == 0
1 & 0   == 0
1 & 1   == 1

Oder kompakter:

x & 0   == 0
x & 1   == x

Beachten Sie, dass dies bedeutet, dass, wenn wir zwei Zahlen UND-verknüpft haben, der resultierende Wert so sein wird, dass alle Bits, die mit Null UND-verknüpft sind, auf Null gesetzt werden, während alle anderen Bits erhalten bleiben. Das heißt, wenn wir UND mit

~(1u << 3)

wir sind UND-ing mit

1111111111110111

In unserer obigen Tabelle bedeutet dies also: “Alle Bits mit Ausnahme des vierten Bits unverändert lassen und dann das vierte Bit auf Null ändern.”

Allgemeiner ausgedrückt: Wenn Sie eine Reihe von Bits löschen möchten, erstellen Sie eine Zahl, die überall dort gleich Eins ist, wo die Bits unverändert bleiben sollen, und dort, wo Sie die Bits löschen möchten, Null ist.

Lassen Sie uns endlich sehen, warum

x ^= (1u << 3)

Kehrt das vierte Bit der Zahl um. Dies liegt daran, dass der binäre XOR-Operator diese Wahrheitstabelle hat:

0 ^ 0  == 0
0 ^ 1  == 1
1 ^ 0  == 1
1 ^ 1  == 0

Beachte das

x ^ 0  == 0
x ^ 1  == ~x

Wo ~x ist das Gegenteil von x; es ist 0 für 1 und 1 für 0. Das bedeutet, wenn wir x mit dem Wert XOR (1u << 3)wir verknüpfen es mit XOR

0000000000001000

Das bedeutet also: “Alle Bits außer dem vierten Bit unverändert lassen, aber das vierte Bit umdrehen.” Allgemeiner gesagt, wenn Sie eine Anzahl von Bits umdrehen möchten, XOR den Wert mit einer Zahl, die Null hat, wo Sie die Bits intakt halten möchten, und eine, wo Sie diese Bits umdrehen möchten.

Hoffe das hilft!

  • 1 << 4 ist das fünfte Bit.

    – Dustin Howett

    2. August 2011 um 18:50 Uhr

  • @Dustin Howett- Danke für den Hinweis! Fest.

    – Vorlagentypdef

    2. August 2011 um 18:50 Uhr

  • Ich erklärte die Bit-Verschiebungen in meiner Antwort, die ganz unten verloren gingen. 1<<3 erzeugt eine Zahl, deren viertes Bit gesetzt ist (0b0001 wird dreimal nach links verschoben, was 0b1000 ergibt) und die binären Operatoren | und & sind 'OR' und 'AND', die auch in einer anderen Antwort unten beschrieben werden.

    – Dustin Howett

    2. August 2011 um 18:55 Uhr

  • Ich würde mich im Allgemeinen unwohl fühlen, wenn ich bitweise Operationen für signierte Typen verwende. Wenn Sie absolut solide sein wollen, verwenden Sie nur vorzeichenlose Typen. (Ganzzahlige Typen ohne Vorzeichen haben eine bestimmte Bitdarstellung.)

    – Kerrek SB

    2. August 2011 um 19:01 Uhr

  • Dies ist die beste Antwort, die ich bisher gelesen habe … so viel klar jetzt!

    – Holzsee

    8. Juni 2014 um 12:39 Uhr

Sie können immer verwenden std::bitset was das Modifizieren von Bits einfach macht.

Oder Sie können Bitmanipulationen verwenden (vorausgesetzt, Sie meinen das 4. Bit, das bei Eins zählt. Subtrahieren Sie nicht 1, wenn Sie von 0 zählen wollen). Beachten Sie, dass ich verwende 1U nur um sicherzustellen, dass die gesamte Operation auf unsigned Nummern stattfindet:

Zum Einstellen: x |= (1U << (4 - 1));

Zu löschen: x &= ~(1U << (4 - 1));

Umschalten: x ^= (1U << (4 - 1));

  • wie funktioniert es ? x |= (1U << (4 - 1)); ?

    – Pedram

    2. August 2011 um 18:56 Uhr

Benutzeravatar von Patrick87
Patrick87

Um das vierte Bit zu setzen, OR mit 00001000 (binär).

Um das vierte Bit zu löschen, AND mit 11110111 (binär).

Um das vierte Bit umzuschalten, XOR mit 00001000 (binär).

Beispiele:

00110010 ODER 00001000 = 00111010

00110010 UND 11110111 = 00110010

00110010 XOR 00001000 = 00111010

Benutzeravatar von Dr. Debasish Jana
Dr. Debasish Jana

Einfach, da Sie haben, oder welchen Wert Sie haben,

int x = 50;

Um das 4. Bit (von rechts) programmatisch zu setzen,

int y = x | 0x00000008;

Da, 0x vor einer Zahl steht bedeutet, dass es sich um eine hexadezimale Form handelt. So, 0x0 = 0000 in binär, und 0x8=1000 in binärer Form. Das erklärt die Antwort.

Probieren Sie eine dieser Funktionen in der Sprache C aus, um n Bit zu ändern

char bitfield;

// start at 0th position

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

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

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

char print_n_bit(int n)
{
    return (bitfield & (1 << n)) ? 1 : 0;
}

Sie können das vierte Bit mit binärem UND und ODER umschalten.

Um das vierte Bit auf x zu setzen, würden Sie verwenden x |= 1<<3;, 1<<3 eine Linksverschiebung von 0b0001 um drei Bits, die 0b1000 erzeugt.

Um das vierte Bit auf x zu löschen, würden Sie verwenden x &= ~(1<<3);ein binäres UND zwischen 0b00110010 (x) und (effektiv) 0b11110111, wobei jedes Bit in x, das sich nicht an Position vier befindet, ausgeblendet und somit gelöscht wird.

1394000cookie-checkÄndern Sie ein bisschen eine ganze Zahl [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy