Was sind bitweise Verschiebungsoperatoren (Bit-Shift) und wie funktionieren sie?

Ich habe versucht, C in meiner Freizeit zu lernen, und andere Sprachen (C#, Java, etc.) haben das gleiche Konzept (und oft die gleichen Operatoren) ...

Ich frage mich, was Bit-Shifting (<<, >>, >>, >>>) im Kern bewirkt, welche Probleme damit gelöst werden können und welche Probleme hinter der Kurve lauern? Mit anderen Worten: ein Leitfaden für absolute Einsteiger in die Bitverschiebung in all ihren Vorzügen.

Lösung

Die Bitverschiebungsoperatoren tun genau das, was ihr Name schon sagt. Sie verschieben Bits. Hier ist eine kurze (oder auch nicht so kurze) Einführung in die verschiedenen Verschiebeoperatoren.

Die Operatoren

  • >> ist der arithmetische (oder vorzeichenbehaftete) Rechtsschiebeoperator.
  • >>> ist der logische (oder vorzeichenlose) Rechtsschiebeoperator.
  • 4), erhalten wir 134,217,734:
00001000 00000000 00000000 00000110

Wenn wir Bits verloren haben, können wir unseren ursprünglichen Wert nicht wiederherstellen.


Arithmetische Rechtsverschiebung (>>)

Die arithmetische Rechtsverschiebung ist genau wie die logische Rechtsverschiebung, nur dass sie nicht mit Null auffüllt, sondern mit dem höchstwertigen Bit. Der Grund dafür ist, dass das höchstwertige Bit das Vorzeichen-Bit ist, also das Bit, das positive und negative Zahlen unterscheidet. Durch das Auffüllen mit dem höchstwertigen Bit ist die arithmetische Rechtsverschiebung vorzeichenerhaltend.

Wenn wir zum Beispiel dieses Bitmuster als negative Zahl interpretieren:

10000000 00000000 00000000 01100000

erhalten wir die Zahl -2.147.483.552. Wenn wir dies mit der arithmetischen Verschiebung (-2.147.483.552 >> 4) um 4 Stellen nach rechts verschieben, erhalten wir:

11111000 00000000 00000000 00000110

oder die Zahl -134.217.722.

Wir sehen also, dass wir das Vorzeichen unserer negativen Zahlen erhalten haben, indem wir die arithmetische Rechtsverschiebung und nicht die logische Rechtsverschiebung verwenden. Und wieder einmal sehen wir, dass wir eine Division durch Potenzen von 2 durchführen.

Kommentare (22)

Nehmen wir an, wir haben ein einzelnes Byte:

0110110

Mit einer einfachen Bitverschiebung nach links erhalten wir:

1101100

Die äußerste linke Null wurde aus dem Byte herausgeschoben, und eine neue Null wurde am rechten Ende des Bytes angehängt.

Die Bits rollen nicht um, sondern werden verworfen. Das heißt, wenn Sie 1101100 nach links schieben und dann nach rechts schieben, erhalten Sie nicht dasselbe Ergebnis zurück.

Eine Linksverschiebung um N ist gleichbedeutend mit einer Multiplikation mit 2N.

Eine Rechtsverschiebung um N ist (bei Verwendung von [Einerkomplement][1]) gleichbedeutend mit einer Division durch 2N und Rundung auf Null.

Bitshifting kann für wahnsinnig schnelle Multiplikationen und Divisionen verwendet werden, vorausgesetzt man arbeitet mit einer Potenz von 2. Fast alle Low-Level-Grafikroutinen verwenden Bitshifting.

In den alten Zeiten haben wir zum Beispiel den Modus 13h (320x200 256 Farben) für Spiele verwendet. Im Modus 13h wurde der Videospeicher sequentiell pro Pixel angelegt. Das bedeutete, dass man zur Berechnung des Speicherplatzes eines Pixels die folgende Rechnung anstellen musste:

memoryOffset = (row * 320) + column

Damals war die Geschwindigkeit entscheidend, daher wurden für diese Operation Bitverschiebungen verwendet.

320 ist jedoch keine Zweierpotenz. Um das zu umgehen, müssen wir herausfinden, welche Zweierpotenz zusammengenommen 320 ergibt:

(row * 320) = (row * 256) + (row * 64)

Jetzt können wir das in Linksverschiebungen umwandeln:


(row * 320) = (row 
Kommentare (6)

Ein Problem besteht darin, dass die folgenden Angaben (nach dem ANSI-Standard) implementierungsabhängig sind:

char x = -1;
x >> 1;

x kann nun 127 (01111111) oder immer noch -1 (11111111) sein.

In der Praxis ist es meist Letzteres.

Kommentare (3)