Da vorzeichenbehaftete Ganzzahlen in der Zweierkomplement -Notation dargestellt werden,
-1
wird 11111111
sein (wenn es eine 8-Bit-Nummer war).
-1 >> 1
evidently signs erweitert sich so, dass es 11111111
bleibt. Dieses Verhalten hängt vom Compiler ab, aber für Microsoft , wenn ein signed verschoben wird number right ( >>
) wird das Vorzeichen-Bit kopiert, während das Verschieben einer vorzeichenlosen Zahl rechts dazu führt, dass 0
in das am weitesten links liegende Bit gesetzt wird.
Eine arithmetische Rechtsverschiebung behält das Zeichen bei, wenn Sie eine signierte Nummer :
%Vor%Im Gegensatz dazu wird eine logische Rechtsverschiebung das Vorzeichen nicht beibehalten:
%Vor%Ihr Code macht eindeutig eine arithmetische Verschiebung, daher wird das Vorzeichenbit ( MSB ) wiederholt. Was der Operator (& gt; & gt;) tut, hängt von den Implementierungsdetails der Plattform ab, die Sie verwenden. In den meisten Fällen ist es eine arithmetische Verschiebung.
Beachten Sie auch, dass 11111111
je nach Darstellung zwei verschiedene Bedeutungen haben kann. Dies beeinflusst auch, wie sie verschoben werden.
11111111
255 dar. Wenn Sie es nach rechts verschieben, wird das Vorzeichen nicht beibehalten, da das MSB kein Vorzeichenbit ist. 11111111
für -1. Arithmetische Verschiebung nach rechts wird das Zeichen erhalten. Das Bit-Shifting einer negativen Zahl ist ein Implementierungsverhalten in C. Die Ergebnisse hängen von Ihrer Plattform ab und könnten theoretisch völlig unsinnig sein. Aus dem C99-Standard (6.5.7.5):
Das Ergebnis von E1 & gt; & gt; E2 ist E1 rechtsverschobene E2-Bitpositionen. Wenn E1 hat einen vorzeichenlosen Typ oder wenn E1 eine hat signierter Typ und ein nicht negativer Wert, Der Wert des Ergebnisses ist der Integraler Bestandteil des Quotienten von E1 / 2 ^ E2. Wenn E1 einen Typ mit Vorzeichen hat und a negativer Wert, der resultierende Wert ist Implementierung definiert.
Der Grund dafür ist, dass Ihr Compiler den x86 SAR-Befehl (Shift Arithmetic Right) verwendet, um & gt; & gt; zu implementieren. Dies bedeutet, dass eine Vorzeichenerweiterung auftreten wird - das höchstwertige Bit wird in das neue MSB repliziert, sobald der Wert umgestellt ist. Aus den Intel Handbüchern :
Das Schichtarithmetikrecht (SAR) und logische logische (SHR) Anweisungen verschieben verschiebe die Bits des Ziels Operand nach rechts (gegen weniger signifikante Bitpositionen). Für jede Verschiebezahl, das niedrigstwertige Bit des Zieloperanden ist verschoben in die CF-Flagge und am meisten signifikantes Bit ist entweder gesetzt oder gelöscht je nach Anweisung Art. Der SHR-Befehl löscht die höchstwertiges Bit (siehe Abbildung 7-8 in der Intel® 64 und IA-32 Architekturen Softwareentwickler Handbuch, Band 1); die SAR-Anweisung Setzt oder löscht die wichtigsten Bit, um dem Zeichen zu entsprechen (die meisten signifikantes Bit) des ursprünglichen Wertes im Zieloperanden. Tatsächlich der SAR-Befehl füllt das leere Bitpositions verschobener Wert mit der Zeichen des unverschobenen Wertes (siehe Abbildung 7-9 in den Intel® 64 und IA-32 Architekturen Softwareentwickler Handbuch, Band 1).
Wenn Sie nach rechts schalten und das linke Bit eine 1 ist, bringen einige Plattformen / Compiler eine 0 und einige behalten die 1 und machen das neue linke Bit zu 1. Dadurch bleibt das Vorzeichen der Zahl erhalten, also eine negative Zahl bleibt negativ und heißt Zeichenerweiterung.
Sie werden den Unterschied sehen, wenn Sie ((unsigned) -1) >> 1
ausprobieren, was eine vorzeichenlose Verschiebung nach rechts bewirkt und daher immer in einem 0-Bit verschoben wird.