Warum ist ein negativer int größer als ein unsigned int? [duplicate]

Lesezeit: 5 Minuten

Benutzeravatar von Slashr
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

Benutzeravatar von WhozCraig
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 int y 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

Benutzeravatar von glglgl
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

Benutzeravatar von Melpomene
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); 

 } 

Benutzeravatar von Suren
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.

1401960cookie-checkWarum ist ein negativer int größer als ein unsigned int? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy