2016-04-13 13 views
-1

Ich habe einige lange lange Konstanten für Grenzen in meinen Berechnungen. Jetzt habe ich ein veraltetes Verhalten, weil einige Bedingungen nicht gültig sind, weil die Nummern "missinterpretiert" sind. Die erste Ausgabe ist die Zahl, die ich verwenden wollte .... in der Ausgabe kann man sehen, dass das - Zeichen entfernt wurde, also dachte ich über einen Unterlauf, aber wenn ich ein 0 hinzufügen, so dass die Zahl noch höher ist, ist die Ausgabe korrekt ....C++ Visual Studio Wired Verhalten von signed Ganzzahl

ich Visual Studio 2012

cout<<-2147483648<<endl; 
cout<<-2147483649<<endl; 
cout<<-21474836480<<endl; 
cout<<-21474836490<<endl; 
cout<<-214748364800<<endl; 
cout<<-214748364900<<endl; 

wie Sie sehen können, bin mit in die ersten 2 Zeilen das - Zeichen wird entfernt

2147483648 
2147483647 
-21474836480 
-21474836490 
-214748364800 
-214748364900 

irgendeine Idee, was ist das Problem hier?

+0

https://en.wikipedia.org/wiki/Integer_overflow – Boiethios

+0

Ihr Beispiel nicht kompiliert auch in VS2012 . Es schlägt mit der folgenden Fehlermeldung für diese 2 Zeilen fehl: "Fehler C4146: unärer Minus-Operator, der auf vorzeichenlosen Typ angewandt wird, Ergebnis noch vorzeichenlos". –

Antwort

1

Sie sollten eine Warnmeldung sorgfältig prüfen, die Ihr Compiler Ihnen gibt. Wenn Ihr Code keine Warnungen erzeugt, sollten Sie die Warnstufe für die Generierung Ihres Compilers erhöhen. Dieser Code auf MSVC Compiler zwei Warnungen erzeugen:

Warnung C4146: unäre Minusoperator auf unsigned Typ angewendet, führen noch unsigned

was im Grunde bedeutet, ist, dass Compiler Bedrohung ersten beiden Werte als unsigned int, dann gelten sie als unärer Minusoperator. Um dieses Problem zu lösen, sollten Sie den Werttyp implizit deklarieren:

cout << -(long long)2147483649 << endl; 
+0

thx viel! Ich muss sogar lange dauern test = - (long long) 2147483648 – user2071938

+1

Wo das 'LL' Suffix ist wahrscheinlich der Weg zu gehen (anstelle der Besetzung) und wenn Sie auf einem aktuellen Compiler sind, können Sie einfach tun:' auto Wert = -214748364900LL; ' – Pixelchemist

2

Compilerwarnungen dürfen nicht ignoriert werden!

Da Sie Ihre Integer-Literale nicht suffigieren, verwendet der Compiler int für Werte kleiner als INT_MAX und unsigned int für Werte zwischen INT_MAX und UINT_MAX. Unter der Annahme einer 2-Komplement-32-Bit-Plattform ist INT_MAX 2147483647, so dass 2147483648 und 2147483648 nicht vorzeichenbehaftet sind, und wie durch die Warnung gesagt, gibt ein Minuszeichen auf einen vorzeichenlosen Typ immer noch einen positiven Wert an. Die Ergebnisse sind also auf einen Überlauf zurückzuführen.

Der richtige Weg ist, um die Litteral mit L für long und LL für long long Suffix:

cout<<-2147483648LL<<endl; 
cout<<-2147483649LL<<endl; 
cout<<-21474836480LL<<endl; 
cout<<-21474836490LL<<endl; 
cout<<-214748364800LL<<endl; 
cout<<-214748364900LL<<endl;