11 Stimmen

Datentyp-Promotions bei arithmetischen Operationen: -1 < (unsinged int) 1 == false

main()  {   
  if ( -1 < (unsigned char) 1 )
    printf("less than");
  else        
    printf("NOT less than");
} 

Drucke less than . Weil, (unsigned char) 1 wird umgewandelt in (signed char) 1 und dann: (signed) -1 < (signed) 1 Die Ausgabe ist also less than .

Aber wenn ich den obigen Code ändere a if ( (-1 < (unsigned int) 1 )

dann lautet die Ausgabe NOT less than .

Es ist also offensichtlich, dass, wenn ich unsigned char zu unsigned int:

  • (vorzeichenbehaftet) -1 wird in unsigned int umgewandelt [genau das Gegenteil passiert].
  • da -1 als 2er-Komplement von 1 gespeichert wird; das Bitmuster wird (wahrscheinlich) als 255 ausgewertet
  • Somit wird 255 < 1 zu false ausgewertet und else ausgeführt.
  • auch wenn Sie die int a = -1; anstelle von '-1' dasselbe Ergebnis

Fragen:

  1. bei vorzeichenbehafteter und vorzeichenloser Arithmetik...wie kann man sicher sein, dass vorzeichenbehaftete in vorzeichenlose Zahlen umgewandelt werden oder umgekehrt.

  2. Warum ist die Konvertierung für die Arithmetik zwischen unsigned char und char unterschiedlich: unsigned wird offenbar in signed umgewandelt und unsigned int und int: signed wird offenbar in unsigned umgewandelt

PS: Ich weiß, dass dies nicht compilerabhängig ist, also sagen Sie nicht, dass es das ist.

10voto

Mark Byers Punkte 761508

Die Regeln lauten wie folgt:

6.3.1.8 Übliche arithmetische Umrechnungen

...

Andernfalls werden die ganzzahligen Promotionen an beiden Operanden durchgeführt. Dann gilt die werden die folgenden Regeln auf die promotierten Operanden angewandt:

  1. Wenn beide Operanden den gleichen Typ haben, ist keine weitere Umwandlung erforderlich.
  2. Andernfalls, wenn beide Operanden vorzeichenbehaftete Ganzzahlen oder vorzeichenlose Ganzzahlen sind, wird der Operand mit dem Typ des niedrigeren Rangs der Ganzzahlumwandlung in den Typ des Operanden mit dem höheren Rang umgewandelt.
  3. Andernfalls, wenn der Operand vom Typ Ganzzahl ohne Vorzeichen einen Rang hat, der größer oder gleich dem Rang des Typs des anderen Operanden ist, wird der Operand vom Typ Ganzzahl mit Vorzeichen in den Typ des Operanden vom Typ Ganzzahl ohne Vorzeichen umgewandelt.
  4. Andernfalls, wenn der Typ des Operanden mit vorzeichenbehaftetem Integer-Typ alle Werte des Typs des Operanden mit vorzeichenlosem Integer-Typ darstellen kann, wird der Operand mit vorzeichenlosem Integer-Typ in den Typ des Operanden mit vorzeichenbehaftetem Integer-Typ konvertiert.
  5. Andernfalls werden beide Operanden in den vorzeichenlosen Ganzzahltyp konvertiert, der dem Typ des Operanden mit vorzeichenbehaftetem Ganzzahltyp entspricht.

Die Regeln funktionieren dann wie folgt:

  • -1 < (unsigned char) 1

Zunächst werden beide Operanden in ints umgewandelt (da ein int alle Werte von unsigned char darstellen kann). Dann wird der Vergleich mit diesen vorzeichenbehafteten Typen durchgeführt. Dann wird Regel 1 angewendet. Der Vergleich ist erfolgreich.

  • -1 < (unsigned int) 1

Da ein int nicht alle Werte eines unsigned int darstellen kann, wird Regel 3 angewendet und die vorzeichenbehaftete ganze Zahl in eine unsigned integer (UINT_MAX - 1) umgewandelt. Der Vergleich schlägt nun fehl.

1voto

ninjalj Punkte 40810

Dies ist zurückzuführen auf Ganzzahlige Beförderungen . Da beide Argumente als int dargestellt werden können, werden sie in einen int umgewandelt.

ISO C 6.3.1.1, Absatz 2:

Wenn ein int alle Werte des ursprünglichen Typs darstellen kann, wird der va andernfalls wird er in einen int ohne Vorzeichen umgewandelt. Diese werden als Integer bezeichnet Promotionen.48) Alle anderen Typen werden durch die Integer-Promotionen nicht verändert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X