Warum erzeugen -1 1 und 0xFFFFFFFF 1 unterschiedliche Ergebnisse?

8

Ich versuche einen Test zu machen, um zu sagen, ob mein PC eine arithmetische oder logische Rechtsverschiebung durch Rechtsverschiebung von Hexadezimal FFFFFFFF by 1 durchführt.

Ich weiß, dass eine Ganzzahl -1 als FFFFFFFF in Hexadezimal gelesen wird, da es das Zweierkomplement von 1 ist. Die rechte Verschiebung von -1 nach 1 ergibt FFFFFFFF und zeigt an, dass der PC arithmetische Rechtsverschiebung ausgeführt hat.

Aber wenn ich nur 0xFFFFFFFF >> 1 eintippe, ergibt sich 7FFFFFFF und zeigt an, dass der PC stattdessen eine logische Rechtsverschiebung durchgeführt hat. Warum ist das passiert? Sehen Sie für den folgenden Code, der die Ergebnisse hervorbrachte:

%Vor%

Die Ausgabe des Programms war:

%Vor%     
vxs8122 10.07.2014, 02:29
quelle

2 Antworten

7

Es ist keine Annahme. Was type glaubst du, 0xffffffff ist? Gemäß dem C-Standard, 6.4.4.1 Integer-Konstanten , ist der -Typ des Ausdrucks einer hexadezimalen -Konstante (mit 0x vorangestellt) der erste der folgenden, der den dargestellten Wert enthalten kann:

%Vor%

Auf Ihrer Plattform kann 0xFFFFFFFF nicht als int dargestellt werden, da int 32 Bits und nur 31 Bits die Menge in signed int ausdrücken (der Standard schreibt vor, dass ein Bit für das Zeichen reserviert ist). Der nächste Typ, unsigned int , wird daher verwendet. Daher ist kein Vorzeichenbit vorhanden, das mit der Schiebeoperation verlängert wird, die dadurch logischer statt arithmetisch ist.

Es ist vielleicht nicht ersichtlich, wie ich festgestellt habe, dass int 32 Bits auf Ihrer Plattform waren. Tatsächlich könnte ich diese Annahme nicht machen, wäre da nicht die erste -Zeile, die arithmetisch-rechts-verschiebt den Wert von -1 . Das Ergebnis dieser Verschiebung, ausgegeben als %x , war 0xFFFFFFFF . Hatte int native 64-Bits, die stattdessen 0xFFFFFFFFFFFFFFFF dumpen sollten. Ohne dieses Vorwissen könnte keine einzelne Typkonklusion von 0xFFFFFFFF angenommen werden, da sie durchaus als standard signed int der Breite 64-Bits (63 + 1) mit dem Wert 0x00000000FFFFFFFF darstellbar wäre. Die resultierende Verschiebung würde die gleiche Ausgabe erzeugen, die Sie jetzt sehen, wodurch eine Alternative zu der oben vorgeschlagenen eingeführt wird.

    
WhozCraig 10.07.2014, 02:39
quelle
6

Ihre Hauptfrage ist: ist 0xffffffff unsigned?

Ab C11 §6.4.4.1 Integer-Konstanten

  

Der Typ einer Integer-Konstante ist der erste der entsprechenden Liste, in dem ihr Wert stehen kann   dargestellt werden.

     

Die Ausgabe Ihrer ersten Zeile printf weist darauf hin, dass int 32-Bit auf Ihrem Computer ist. Daher kann es nicht 0xffffffff darstellen, es muss vorzeichenlos sein.

    
Yu Hao 10.07.2014 02:38
quelle

Tags und Links