Warum ist ein negativer int größer als ein unsigned int? [duplicate]
Lesezeit: 5 Minuten
Slashr
int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > y)
Printf("x is greater");
else
Printf("y is greater");
getch();
return (0);
}
Output: x is greater
Ich dachte, die Ausgabe wäre y ist größer, da es unsigned ist. Was ist der Grund dafür?
Das sollte Sie warnen?
– asheshr
28. November 2012 um 8:48 Uhr
WhozCraig
Weil die int Wert wird zu einem befördert unsigned int. speziell 0xFFFFFFFC auf einem 32-Bit-Rechner, der als unsigned int ist 4294967292deutlich größer als 10
C99 6.3.1.1-p2
Wenn ein Int alle Werte des ursprünglichen Typs darstellen kann (bei einem Bitfeld durch die Breite eingeschränkt), wird der Wert in einen Int umgewandelt; andernfalls wird es in ein konvertiert unsigned int. Diese werden als Integer-Promotions bezeichnet. Alle anderen Typen bleiben von den Integer-Promotions unverändert.
So führen Sie die Konvertierung durch:
C99 6.3.1.3-p2
Andernfalls, wenn der neue Typ vorzeichenlos ist, wird der Wert konvertiert, indem wiederholt eins mehr als der maximale Wert, der im neuen Typ dargestellt werden kann, addiert oder subtrahiert wird, bis der Wert im Bereich des neuen Typs liegt.
Was im Grunde “UINT_MAX + 1 hinzufügen” bedeutet (so wie ich es jedenfalls lese).
In Bezug darauf, warum die Beförderung zum unsigned int Seite; Vorrang:
C99 6.3.1.8-p1
…Andernfalls, wenn der Rang des Operanden vom Typ Ganzzahl ohne Vorzeichen 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 konvertiert.
Andernfalls, wenn der Typ des Operanden mit vorzeichenbehafteter Ganzzahl alle Werte des Typs des Operanden mit vorzeichenloser Ganzzahl darstellen kann, wird der Operand mit vorzeichenloser Ganzzahl in den Typ des Operanden mit vorzeichenbehafteter Ganzzahl konvertiert.
Was mir sagt int vs. unsigned char sollte wie erwartet funktionieren.
Prüfen
int main()
{
int x = -4;
unsigned int y = 10;
unsigned char z = 10;
if (x > y)
printf("x>y\n");
else
printf("x<y\n");
if (x > z)
printf("x>z\n");
else
printf("x<z\n");
return 0;
}
Ausgabe
x>y
x<z
Nun schau dir das an.
Ich frage mich, warum die unsigned inty wird nicht konvertiert signed int da es im Bereich von liegt unsigned int
– Anirudha
28. November 2012 um 9:05 Uhr
Der relevante Abschnitt ist eigentlich 6.3.1.8 Übliche arithmetische Umrechnungen. Es heißt: “… Andernfalls, wenn der Operand mit dem Typ der vorzeichenlosen Ganzzahl einen Rang hat, der größer oder gleich dem Rang des Typs des anderen Operanden ist, dann wird der Operand mit dem Typ der vorzeichenbehafteten Ganzzahl in den Typ des Operanden mit der vorzeichenlosen Ganzzahl konvertiert Typ.” (int und unsigned int gleichrangig sind).
– Melpomen
28. November 2012 um 9:10 Uhr
Natürlich nicht, mach weiter und steck es ein.
– Melpomen
28. November 2012 um 9:14 Uhr
glglgl
Ein Vergleich zwischen einem vorzeichenbehafteten und einem vorzeichenlosen Wert wird im “unsigned space” durchgeführt. Dh der vorzeichenbehaftete Wert wird durch Addition in einen vorzeichenlosen umgewandelt UINT_MAX + 1. Bei der Implementierung unter Verwendung des 2er-Komplements für negative Werte ist keine spezielle Behandlung der Werte unter der Haube erforderlich.
In diesem Beispiel ist die -4 wird zu einem 0x100000000-4 = 0xFFFFFFFC was klar ist > 10.
Es ist großartig, heruntergestimmt zu werden, während man noch an der Antwort arbeitet … und ohne Vorankündigung, was der Herabwähler für falsch hält
– glglgl
28. November 2012 um 8:48 Uhr
Das Verhalten ist nicht implementierungsabhängig und hat nichts mit dem Zweierkomplement zu tun.
– Melpomen
28. November 2012 um 8:53 Uhr
Nein, nein, ganz im Gegenteil. Die Antwort ist richtig, wie alle Antworten auf dieser Seite. Es ist eine triviale Sache für alle erfahrenen C-Programmierer.
– Israel Untermann
28. November 2012 um 8:55 Uhr
Nein, jede Antwort, die “Zweierkomplement” erwähnt, ist falsch. C benötigt zur Laufzeit nicht einmal das Zweierkomplement, trotzdem ist das Verhalten zu 100% spezifiziert.
– Melpomen
28. November 2012 um 8:57 Uhr
Was also, wenn es nicht erforderlich ist? Die Implementierung macht das Zweierkomplement. Sie können in unsigned umwandeln und den Wert überprüfen.
– Israel Unterman
28. November 2012 um 8:59 Uhr
Melpomene
Wenn Sie zwei Werte in C vergleichen, müssen beide vom gleichen Typ sein. In diesem Fall (int und unsigned int) das int Der Wert wird in ein umgewandelt unsigned int Erste.
Zweitens wird vorzeichenlose Integer-Arithmetik in C modulo dem Maximalwert dieses Typs + 1 durchgeführt (d. h. es wird so “umgebogen”. UINT_MAX + 1 ist 0 wieder und umgekehrt). Daher führt die Umwandlung negativer Werte in vorzeichenlose Ergebnisse zu sehr großen Zahlen.
Der entsprechende Abschnitt in der Norm sagt:
6.3.1.3 Ganzzahlen mit und ohne Vorzeichen
2
Andernfalls, wenn der neue Typ vorzeichenlos ist, wird der Wert konvertiert, indem wiederholt eins mehr als der maximale Wert, der im neuen Typ dargestellt werden kann, addiert oder subtrahiert wird, bis der Wert im Bereich des neuen Typs liegt.
+1 Ich stimme der Konvertierung zu. Ich brauchte eine Minute, um den Grund zu finden warum es wird an erster Stelle durchgeführt (6.3.1.1-p2). Das wie so wie du es hier beschrieben hast, trifft es zu.
– WhozCraig
28. November 2012 um 9:08 Uhr
Das ist eigentlich der falsche Teil. 🙂 6.3.1.1/2 gilt nur für Typen “kleiner” als int/unsigned int, die anstelle von int/unsigned int verwendet werden.
– Melpomen
28. November 2012 um 9:14 Uhr
Wenn Sie ein vergleichen int und ein unsigned int das int umgewandelt wird unsigned int. Die Umwandlung einer int zu einem unsigned int erfolgt durch Hinzufügen UINT_MAX+1 (Beachten Sie, dass Ihre int ist negativ). Also eigentlich vergleichst du:
if (-3 + UINT_MAX > 10) //Since -4 is converted to UINT_MAX+1-4
Was wahr ist.
Das erste Bit eines int-Werts wird verwendet, um zu definieren, ob es sich um einen positiven oder einen negativen Wert handelt. (1 = negativ, 0 positiv) Ihre beiden Variablen werden vor dem Vergleich in unsigned int umgewandelt, wobei die 1 im ersten Bit als Teil Ihrer Zahl interpretiert wird.
Dieser Code sollte gut funktionieren:
int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > (int) y)
Printf("x is greater");
else
Printf ("y is greater");
getch ( );
return (0);
}
sicher
int x=-4 (2er-Komplement von 4 ist 1111 1100 = 252) und unsigned int y=10 ist (0000 1010 = 10), also 252 > 10, also ist -4 größer als 10.
14019600cookie-checkWarum ist ein negativer int größer als ein unsigned int? [duplicate]yes
Das sollte Sie warnen?
– asheshr
28. November 2012 um 8:48 Uhr