Bitverschiebungsoperator in C++

Anam Javed 12 Oktober 2023
  1. Linker Bitverschiebungsoperator in C++
  2. Rechter Bitverschiebungsoperator in C++
  3. Bitverschiebung bei Float-Datentyp in C++
  4. Bitverschiebung im Array in C++
  5. Bitverschiebung und Maske in C++
  6. Bitverschiebung für negative Zahlen in C++
  7. Bitverschiebung mit Long in C++
  8. Fazit
Bitverschiebungsoperator in C++

In C++ tun Bitverschiebungsoperatoren das, was ihr Name vermuten lässt, nämlich das Verschieben von Bits. Entsprechend den Anforderungen des Programms verschiebt ein bitweiser Schiebeoperator die binären Bits nach links oder rechts.

Auf diese Operatoren werden ganzzahlige Werte angewendet (int, long, möglicherweise short und byte oder char). In einigen Sprachen ändert die Verwendung der Umschaltoperatoren bei jedem Datentyp, der kleiner als int ist, automatisch die Größe des Operanden auf einen int.

In diesem Artikel werden die Left- und Right-Shift-Operatoren in C++ und ihre Implementierung im Detail zusammen mit relevanten Beispielen erläutert.

Linker Bitverschiebungsoperator in C++

Der linke Verschiebungsoperator verschiebt die Bits im Verschiebungsausdruck um die Anzahl der Stellen im additiven Ausdruck nach links. Die durch die Schiebeoperation frei gewordenen Bitpositionen werden mit Nullen aufgefüllt, und die am Ende verschobenen Bits einschließlich des Vorzeichenbits werden verworfen.

Der Linksverschiebungsoperator nimmt zwei Zahlen. Dies verschiebt die Bits des ersten Operanden, und der zweite Operand bestimmt die Anzahl der zu verschiebenden Stellen.

Man kann sagen, dass die Linksverschiebung einer ganzen Zahl a mit einer ganzen Zahl b, bezeichnet mit (a<<b), gleichbedeutend ist mit der Multiplikation von a mit 2^b (2 potenziert mit b). Der Linksverschiebungsoperator ist mit << gekennzeichnet.

Zum Beispiel M<<k. Dabei ist M der erste Operand und k der zweite Operand.

Nehmen wir M=33; was binär 100001 und k = 2 ist. Wenn M um 2 nach links verschoben wird, was mit M=M<<2 bezeichnet wird, wird es zu M=M(2^2).

Somit kann M=33(2^2)=132 als 10000100 geschrieben werden.

Beispiel:

#include <iostream>
using namespace std;

int main() {
  unsigned char x = 6, y = 7;
  cout << "x<<1 = " << (x << 1) << endl;
  cout << "y<<1 = " << (y << 1) << endl;
  return 0;
}

Ausgabe:

x<<1 = 12
y<<1 = 14

Im obigen Code bezeichnen die vorzeichenlosen Variablen char x und char y einen Zeichendatentyp, bei dem die Variable alle 8 Bits des Speichers verwendet und es kein Vorzeichenbit gibt (das in signed char vorhanden ist).

Hier ist char x gleich 6, d.h. 00000110 in Binärform, und char y ist gleich 7, d.h. 00000111 in Binärform.

Die erste Druckanweisung gibt an, den Wert von x um 1 Bit nach links zu verschieben; das Ergebnis ist 00001100. Die zweite print-Anweisung besagt, dass der Wert von y um 1 Bit nach links verschoben werden soll; das Ergebnis ist 00001110.

Rechter Bitverschiebungsoperator in C++

Der Rechtsverschiebungsoperator verschiebt das Bitmuster im Verschiebungsausdruck um die Anzahl der Stellen, die der additive Ausdruck nach rechts bereitstellt. Die durch die Schiebeoperation frei gewordenen Bitstellen werden für vorzeichenlose Werte mit Nullen aufgefüllt.

Das Vorzeichenbit ersetzt die freien Bitstellen in vorzeichenbehafteten Zahlen. Wenn die Zahl positiv ist, wird der Wert 0 verwendet; wenn die Zahl negativ ist, wird der Wert 1 verwendet.

Der rechte Verschiebungsoperator nimmt zwei Zahlen. Dies verschiebt die Bits des ersten Operanden, und der zweite Operand bestimmt die Anzahl der zu verschiebenden Stellen.

Man kann sagen, dass die Rechtsverschiebung einer ganzen Zahl a durch eine ganze Zahl b, bezeichnet als (a>>b), gleichbedeutend ist mit der Division von a durch 2^b (2 potenziert mit b). Der rechte Verschiebungsoperator wird bezeichnet als: >>.

Zum Beispiel M>>k. Dabei ist M der erste Operand und k der zweite.

Nehmen wir M=32; was binär 100000 und k = 2 ist. Wenn M um 2 nach rechts verschoben wird, was mit M=M>>2 bezeichnet wird, dann wird M zu M=M/(2^2). Somit kann M=32/(2^2)=8 als 1000 geschrieben werden.

Beispielprogramm:

#include <iostream>

int main() {
  unsigned char x = 6, y = 9;
  cout << "a>>1 = " << (a >> 1) << endl;
  cout << "b>>1 = " << (b >> 1) << endl;
  return 0;
}

Ausgabe:

x>>1 = 3
y>>1 = 4

Im obigen Code bezeichnen die vorzeichenlosen Variablen char x und char y einen Zeichendatentyp in der Variablen, der alle 8 Bits des Speichers verwendet, und es gibt kein Vorzeichenbit (das in signed char vorhanden ist).

Hier ist char x gleich 6, d.h. 00000110 in Binärform, und char y ist gleich 9, d.h. 00001001 in Binärform.

Die erste Druckanweisung gibt an, den Wert von x um 1 Bit nach rechts zu verschieben; das Ergebnis ist 00000011. Die zweite print-Anweisung gibt an, den Wert von y um 1 Bit nach rechts zu verschieben; Das Ergebnis ist 00000100.

Bitverschiebung bei Float-Datentyp in C++

Sie können ein Float in C++ nicht bit-shiften, da es einen Fehler anzeigt, aber warum ist das so? Das liegt daran, dass Floats in einem speziellen Format gespeichert werden.

32 Bits für einen Float werden in zwei Kategorien unterteilt: einen Signifikanten und einen Exponenten. Eine Verschiebung kann potentiell Bits von der Exponenten-Kategorie in die Signifikanten-Kategorie verschieben oder umgekehrt.

Beispiel:

#include <stdio.h>

int main(int ar, char *arg[]) {
  float testFl = 2.5;

  printf("testFloat (before): %f\n", testFl);
  testFl = testFl << 1;
  printf("testFloat (after): %f\n", testFl);
  return 0;
}

Ausgabe:

error: invalid operands to binary << (have 'float' and 'int')

Die Rechtsverschiebung oder Linksverschiebung würde alle Bits zusammenbrechen lassen.

Bitverschiebung im Array in C++

Es gibt ein Array ar[] der Grösse n und eine ganze Zahl m.

Das Ziel besteht darin, alle Array-Elemente > m zu machen, indem Rechtsverschiebungsoperationen an allen vorhandenen Array-Elementen durchgeführt werden. Wenn Sie dazu nicht in der Lage sind, geben Sie -1 aus.

Beispiel:

Input: ar[] = { 21, 22, 23, 19 }, m = 34
Output: { 26, 26, 27, 25 }

Explanation:
ar[0] = 10101
After 1 right shift, 11010 → 26
ar[1] = 10110
After 3 right shift, 11010 → 26
ar[2] = 10111
After  1 right shift, 11011 → 27
ar[3] = 10011
After 2 right shift, 11001 → 25

Code:

#include <bits/stdc++.h>
using namespace std;

int setBitNumber(int n) {
  int m = log2(n);
  return m;
}

bool check(int ar[], int m, int n) {
  for (int i = 0; i < n; i++) {
    if (ar[i] <= m) return false;
  }
  return true;
}

void modifyArray(int ar[], int m, int n) {
  for (int i = 0; i < n; i++) {
    if (ar[i] > m)
      continue;
    else {
      int bits = setBitNumber(ar[i]);
      int el = ar[i];
      for (int j = 0; j < bits; j++) {
        if (el & 1) {
          el >>= 1;
          el |= (1 << bits);
        } else {
          el >>= 1;
        }
        if (el > m) {
          arr[i] = el;
          break;
        }
      }
    }
  }

  if (check(ar, m, n)) {
    for (int i = 0; i < n; i++) cout << ar[i] << " ";
  } else
    cout << -1;
}

int main() {
  int ar[] = {21, 22, 23, 19};
  int n = sizeof(ar) / sizeof(ar[0]);
  int m = 24;
  modifyArray(ar, m, n);
  return 0;
}

Ausgabe:

[26, 26, 27, 25]

Die Hauptoperation, die im Programm ausgeführt wird, ist das Durchlaufen des Arrays. Es führt die Rechtsverschiebungsoperation an jedem Element des Arrays ar[i] durch.

Die Bedingung wird geprüft, wenn ar[i] > m. Wenn es wahr ist, dann aktualisiere das Array ar[i], andernfalls fahre fort.

Wenn irgendein Element des Arrays ar[i] ≤ m, dann drucke -1, ansonsten drucke das Array ar[i].

Bitverschiebung und Maske in C++

Eine Maske gibt an, welche Bits beibehalten und welche gelöscht werden sollen.

Beispiel:

Mask:   00001111b
Value:  01010101b

Wenn wir die Maske auf den Wert anwenden, möchten wir die ersten (oberen) vier Bits löschen, während die letzten (unteren) vier Bits erhalten bleiben. Als Ergebnis haben wir die unteren vier Bits abgerufen.

Ausgabe:

Mask:   00001111b
Value:  01010101b
Result: 00000101b

Bitverschiebungsoperatoren werden häufig mit Maskierungsoperationen verwendet, um Bits einzeln von einer Zahl abzulösen. Das folgende Beispiel erläutert, wie ein Zeichen ohne Vorzeichen in ein Array aus separaten Bits aufgeteilt wird.

unsigned char y = 0xD5;
unsigned char bit[8];
unsigned char mask = 1;
for (int x = 7; x >= 0; x--) {
  bits[x] = y & mask;
  y = y >> 1;
}

Bitverschiebung für negative Zahlen in C++

Negative Zahlen sollten nicht mit den linken und rechten Verschiebungsoperatoren eingegeben werden. Wenn einer der Operanden eine negative Ganzzahl ist, ist das Ergebnis ein undefiniertes Verhalten.

Beispielsweise ist das Ergebnis sowohl von 1 >> -1 als auch von 1 << -1 undefiniert.

#include <iostream>

int main() {
  unsigned char x = -6, cout << "a>>1 = " << (a >> 1) << endl;
  return 0;
}

Ausgabe:

error: undefined behavior in C

Bitverschiebung mit Long in C++

Der Datentyp long wird zur Bitverschiebung um 32 Bit oder 64 Bit verwendet.

Beispiel:

Für 32-Bit,

unsigned long A = (1L << 37)

Für 64-Bit,

unsigned long long A = (1ULL << 37);

So implementieren Sie Folgendes mit einem Programm:

#include <stdio.h>

int main(void) {
  long long y = 1ULL;

  // Left shift 40 times
  y <<= 20;
  y <<= 20;

  printf("y is %lld\n", y);
  return 0;
}

Ausgabe:

y is 1099511627776

Hier wird eine 64-Bit-Variable long long y genommen, und 1ULL ist eine vorzeichenlose long long int-Konstante (64 Bit). Die Variable y wird 40-mal verschoben und ausgegeben.

Fazit

In diesem Artikel haben wir den Bitverschiebungsoperator in C++ besprochen. Wir haben die Links- und Rechtsverschiebungsoperatoren in C++ im Detail kennengelernt.

Verwandter Artikel - C++ Operator