2016-05-01 5 views
0

Der MSB sollte mit allen anderen Bits ausgeschaltet werden.Warum ergeben dieselben bitweisen Operationen andere Ergebnisse?

unsigned char a = ~0 <<1>> 1; 
printf("a: %d\n", a); 

unsigned char b = ~0; 
b <<= 1; 
b >>= 1; 
printf("b: %d\n", b); 

Der Ausdruck gibt:

a: 255 
b: 127 
+1

Ihre Snippets basieren auf implementiertem definiertem Verhalten. Und Sie verwenden den falschen Typ-Spezifizierer, um '' unsigned char'' zu drucken. – Olaf

+0

Sieht für mich die Betreiber mit unterschiedlicher Priorität binden. –

+0

@WillemVanOnsem Das Hinzufügen von Klammern, um die Prioritäten explizit zu machen, macht keinen Unterschied. – OneZero

Antwort

3

Integer Förderung Regeln gelten.

Die Integer-Aktionen werden für jeden der Operanden ausgeführt. Der Typ des Ergebnisses ist der des hochgestuften linken Operanden.

Die RHS der Initialisierung:

unsigned char a = ~0 <<1>> 1; 

wandelt 0 zu int, dann ist links bitweise und rechts verschiebt, und dann schließlich die Zuordnung setzt das Ergebnis in unsigned char. Dies bedeutet, dass das Ergebnis 255 ist (unter der Annahme CHAR_BIT == 8). Technisch gesehen, haben Sie undefiniertes Verhalten:

Das Ergebnis E1 << E2 ist E1 nach links verschobenen E2 Bit-Positionen; Freigegebene Bits werden mit Nullen gefüllt. Wenn E1 einen vorzeichenlosen Typ hat, ist der Wert des Ergebnisses E1 × 2 E2, reduzierter Modulo ein Wert mehr als der Maximalwert, der im Ergebnistyp dargestellt werden kann. Wenn E1 einen signierten Typ und einen nichtnegativen Wert hat und E1 × 2 E2 im Ergebnistyp darstellbar ist, dann ist das der resultierende Wert; Andernfalls ist das Verhalten nicht definiert.

würden Sie nicht definiertes Verhalten vermeiden, wenn Sie verwendet:

unsigned char a = ~0U <<1>> 1; 

Die ‚Mehrfachzuordnungen‘ -Version (nicht definiertes Verhalten zu vermeiden) ist äquivalent zu:

unsigned char a = (unsigned char)(~0U << 1) >> 1; 

, die das Ergebnis der kürzt Verschiebung nach links, bevor der Typ für die Verschiebung nach rechts erneut unterstützt wird, und würde 127 als Ergebnis ergeben (immer noch CHAR_BIT == 8 vorausgesetzt).

Verwandte Themen