(-1 1) == -1 - Warum?

7

Warum ergibt (-1 >> 1) in -1 ? Ich arbeite in C, obwohl ich denke, dass das nicht wichtig sein sollte.

Ich kann nicht herausfinden, was ich vermisse ...

Hier ist ein Beispiel für ein C-Programm, das die Berechnung durchführt:

%Vor%     
Frank V 26.06.2009, 01:33
quelle

5 Antworten

23

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.

    
David Johnstone 26.06.2009, 01:38
quelle
11

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.

  • Wenn nicht vorzeichenbehaftet, stellt 11111111 255 dar. Wenn Sie es nach rechts verschieben, wird das Vorzeichen nicht beibehalten, da das MSB kein Vorzeichenbit ist.
  • Wenn signiert, steht 11111111 für -1. Arithmetische Verschiebung nach rechts wird das Zeichen erhalten.
Wadih M. 26.06.2009 01:42
quelle
5

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).

    
bdonlan 26.06.2009 01:36
quelle
3

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.

    
John Kugelman 26.06.2009 01:38
quelle
1

Zeichenerweiterung.

    
smcameron 26.06.2009 01:35
quelle

Tags und Links