HOWTO · C

So vergleichen Sie Bits in C

Dieser Artikel zeigt, wie man Bits in C vergleicht.

Auf dieser Seite

Bitweise Operationen sind in der Computerprogrammierung grundlegend, insbesondere bei der Datenmanipulation auf niedriger Ebene. In C gibt es mehrere Methoden, um einzelne Bits oder Gruppen von Bits zu vergleichen.

In diesem Artikel werden wir verschiedene Techniken zusammen mit Codebeispielen untersuchen, um jede Methode zu demonstrieren.

Implementieren Sie eine benutzerdefinierte Funktion mit bitweisen XOR- und AND-Operationen für den Bitvergleich in C

Der bitweise AND-Operator (&) wird verwendet, um einen bitweisen Vergleich zwischen den entsprechenden Bits zweier Operanden durchzuführen. Diese Operation ergibt einen neuen Wert, bei dem jedes Bit genau dann gesetzt ist, wenn die entsprechenden Bits in beiden Operanden gesetzt sind.

Beispielcode:

#include <stdio.h>

int main() {
  unsigned int num1 = 9;  // Binary representation: 1001
  unsigned int num2 = 6;  // Binary representation: 0110

  unsigned int result = num1 & num2;

  printf("Result: %u\n", result);  // Output: 0 (Binary: 0000)

  return 0;
}

Ausgabe:

Result: 0

In diesem Beispiel werden num1 und num2 mit den Werten 9 bzw. 6 initialisiert. Diese Werte werden binär als 1001 und 0110 dargestellt.

Die bitweise AND-Operation zwischen num1 und num2 (num1 & num2) ergibt binär 0000, also dezimal 0. Das bedeutet, dass keine entsprechenden Bits sowohl in num1 als auch in num2 gesetzt sind.

Der bitweise XOR-Operator (^) wird dagegen verwendet, um einen bitweisen Vergleich zwischen den entsprechenden Bits zweier Operanden durchzuführen. Diese Operation ergibt einen neuen Wert, bei dem jedes Bit gesetzt ist, wenn die entsprechenden Bits in den Operanden unterschiedlich sind.

Beispielcode:

#include <stdio.h>

int main() {
  unsigned int num1 = 9;  // Binary representation: 1001
  unsigned int num2 = 6;  // Binary representation: 0110

  unsigned int result = num1 ^ num2;

  printf("Result: %u\n", result);  // Output: 9 (Binary: 1001)

  return 0;
}

Ausgabe:

Result: 15

In diesem Beispiel ergibt die bitweise XOR-Operation (num1 ^ num2) binär 1001, also dezimal 9. Das bedeutet, dass die entsprechenden Bits in num1 und num2 unterschiedlich sind.

Im Allgemeinen umfasst der Bitvergleich den Zugriff auf Einzelbitwerte und die Durchführung der erforderlichen Operationen, z. B. das Implementieren eines Bitfelds mit den Schlüsselwörtern union und struct.

Bitweise Operationen bieten jedoch eine effizientere Methode zum Vergleichen bestimmter Bits in Zahlen. In diesem Fall implementieren wir eine separate Funktion, die für den Typ u_int32_t geeignet ist und eine Breite von 32 Bit garantiert.

Das folgende Beispielprogramm verwendet drei Ganzzahlen als Befehlszeilenargumente, von denen die ersten beiden die verglichenen Zahlen sind, während die dritte Ganzzahl das n-te Bit angibt. Beachten Sie, dass wir argv-Elemente mit strtol konvertieren und dadurch beim Speichern der Rückgabewerte im Typ u_int32_t an Genauigkeit verlieren.

Die Funktion compareBits deklariert zwei lokale Variablen, in denen Zwischenwerte gespeichert sind - mask und tmp. Wir setzen das n-te Bit in der mask, indem wir die 1 um die Positionen nth - 1 nach links verschieben.

Dann werden beide Benutzereingabenummern XOR-verknüpft, um die Bitunterschiede an jeder Position zu erhalten, wobei ein gesetztes Bit im Ergebnis unterschiedliche Werte angibt. Schließlich müssen wir das Bit aus der n-ten Position extrahieren und prüfen, ob der Wert 0 ist.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
  u_int32_t mask, tmp;

  mask = 1 << (nth - 1);
  tmp = n1 ^ n2;

  if ((tmp & mask) == 0)
    return true;
  else
    return false;
}

int main(int argc, char *argv[]) {
  u_int32_t num1, num2, bit;

  if (argc != 4) {
    fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
    exit(EXIT_FAILURE);
  }

  num1 = strtol(argv[1], NULL, 0);
  num2 = strtol(argv[2], NULL, 0);
  bit = strtol(argv[3], NULL, 0);

  compareBits(num1, num2, bit) ? printf("bits equal!\n")
                               : printf("bits not equal!\n");

  exit(EXIT_SUCCESS);
}

Beispieldateiformat:

./main 1234 1231 1

Eingabedateiformat:

bits not equal!

Beispielsweise werden die Ganzzahlen 1234 und 1231 binär als 00000000000000000000010011010010 bzw. 00000000000000000000010011001111 dargestellt.

Das XOR-Verknüpfen dieser beiden Zahlen ergibt somit die binäre Darstellung 00000000000000000000000000011101, die schließlich mit der Maske 00000000000000000000000000000010 AND-verknüpft wird, um den Wert der Einzelbitposition zu extrahieren. Wenn das Ergebnis nur aus Nullen besteht, bedeutet dies, dass die verglichenen Bits gleich sind; andernfalls ist es umgekehrt.

Alternativ können wir jedoch die Funktion compareBits kürzen und die XOR/AND-Operationen in die return-Anweisung verschieben, wie im folgenden Beispielcode gezeigt. Beachten Sie, dass die Funktion das logische Gegenteil der bitweisen XOR/AND-Operationen zurückgibt, da wir die entsprechenden Nachrichten in der Aufruferfunktion mit der ternären Anweisung ? : ausgeben.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
  u_int32_t mask;

  mask = 1 << (nth - 1);

  return !((n1 ^ n2) & mask);
}

int main(int argc, char *argv[]) {
  u_int32_t num1, num2, bit;

  if (argc != 4) {
    fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
    exit(EXIT_FAILURE);
  }

  num1 = strtol(argv[1], NULL, 0);
  num2 = strtol(argv[2], NULL, 0);
  bit = strtol(argv[3], NULL, 0);

  compareBits(num1, num2, bit) ? printf("bits equal!\n")
                               : printf("bits not equal!\n");

  exit(EXIT_SUCCESS);
}

Beispieldateiformat:

./main 1234 1231 2

Eingabedateiformat:

bits equal!

Verwenden Sie den bitweisen OR-Operator (|) für den Bitvergleich in C

Der bitweise OR-Operator (|) führt einen bitweisen Vergleich zwischen den entsprechenden Bits zweier Operanden durch. Das Ergebnis dieser Operation ist ein neuer Wert, bei dem jedes Bit gesetzt ist, wenn mindestens eines der entsprechenden Bits in einem der beiden Operanden gesetzt ist.

Auf ein Bitpaar angewendet, folgt die OR-Operation dieser Logik:

`0 0`
`0 1`
`1 0`
`1 1`

Betrachten Sie das folgende Beispiel zur Veranschaulichung der bitweisen OR-Operation:

#include <stdio.h>

int main() {
  unsigned int num1 = 9;  // Binary representation: 1001
  unsigned int num2 = 6;  // Binary representation: 0110

  unsigned int result = num1 | num2;

  printf("Result: %u\n", result);  // Output: 15 (Binary: 1111)

  return 0;
}

Ausgabe:

Result: 15

In diesem Beispiel haben wir zwei vorzeichenlose Ganzzahlen, num1 und num2, die mit den Werten 9 bzw. 6 initialisiert sind. Ihre binären Darstellungen sind 1001 und 0110.

Wenn wir die bitweise OR-Operation (num1 | num2) ausführen, ist das Ergebnis binär 1111, also dezimal 15. Das bedeutet, dass mindestens eines der entsprechenden Bits in num1 oder num2 gesetzt ist.

Verwenden Sie den bitweisen NOT-Operator (~) für den Bitvergleich in C

Der bitweise NOT-Operator (~) ist ein unärer Operator, d. h. er arbeitet mit einem einzigen Operanden. Auf eine Binärzahl angewendet, invertiert er jedes Bit, indem er 0en in 1en und 1en in 0en verwandelt.

Beispielcode:

#include <stdio.h>

int main() {
  unsigned int num = 9;  // Binary representation: 1001

  unsigned int result = ~num;

  printf(
      "Result: %u\n",
      result);  // Output: 4294967286 (Binary: 11111111111111111111111111111010)

  return 0;
}

Ausgabe:

Result: 4294967286

In diesem Beispiel deklarieren wir eine vorzeichenlose Ganzzahlvariable num und initialisieren sie mit dem Wert 9. Binär wird dies als 1001 dargestellt.

Dann wenden wir den bitweisen NOT-Operator (~num) an. Dadurch werden alle Bits invertiert, was binär 11111111111111111111111111111010 ergibt.

Das Ergebnis wird auf der Konsole ausgegeben und lautet dezimal 4294967286.

Bitweises NOT zum Vergleichen von Bits

Eine der Anwendungen des bitweisen NOT-Operators ist der Vergleich von Bits. Indem wir die Bits einer Variablen invertieren, können wir leicht prüfen, ob ein bestimmtes Bit gesetzt ist oder nicht.

Beispielcode:

#include <stdio.h>

int main() {
  unsigned int num = 9;  // Binary representation: 1001

  // Check if the 2nd bit is set
  unsigned int mask = 1 << 1;  // Shift 1 by 1 position to the left => 0002

  unsigned int result = ~num & mask;

  if (result == mask) {
    printf("2nd bit is set.\n");
  } else {
    printf("2nd bit is not set.\n");
  }

  return 0;
}

Ausgabe:

2nd bit is set.

In diesem Beispiel möchten wir prüfen, ob das 2. Bit der Variablen num gesetzt ist.

Wir erstellen zunächst eine Maske, indem wir die 1 um 1 Position nach links verschieben (1 << 1), was binär 0002 ergibt. Dann wenden wir den bitweisen NOT-Operator auf num an, was binär 11111111111111111111111111111010 ergibt.

Als Nächstes führen wir eine bitweise AND-Operation zwischen dem invertierten num und der Maske aus. Dadurch wird das 2. Bit isoliert.

Wenn das Ergebnis gleich der Maske ist, bedeutet dies, dass das 2. Bit gesetzt ist, und wir geben eine entsprechende Nachricht aus. Andernfalls geben wir eine Nachricht aus, die angibt, dass das 2. Bit nicht gesetzt ist.

Fazit

In dieser umfassenden Untersuchung bitweiser Operatoren in C haben wir grundlegende Operationen wie AND, OR und NOT behandelt. Diese Operationen sind für Aufgaben mit Datenmanipulation auf niedriger Ebene von unschätzbarem Wert, z. B. Datenkompression, Verschlüsselung und Programmierung eingebetteter Systeme.

Insbesondere haben wir uns mit der Verwendung des bitweisen NOT-Operators (~) zum Vergleichen einzelner Bits befasst. Durch Anwenden des ~-Operators können wir die Bits einer Variablen leicht invertieren und so prüfen, ob ein bestimmtes Bit gesetzt ist oder nicht. Diese Technik ist in Szenarien unerlässlich, in denen eine präzise Manipulation auf Bitebene erforderlich ist.

Das Verstehen und Beherrschen bitweiser Operationen ist für Programmierer entscheidend, die an Aufgaben arbeiten, die eine direkte Interaktion mit Hardware beinhalten oder optimierte Lösungen für ressourcenbeschränkte Umgebungen erfordern. Mit dem Wissen aus diesem Artikel sind Sie nun in der Lage, diese leistungsstarken Werkzeuge in Ihren eigenen C-Programmierprojekten einzusetzen.