2010-09-01 12 views
46

In C# Ich sehe, dass-1 * int.MinValue == int.MinValue ?? Ist das ein Fehler?

-1 * int.MinValue == int.MinValue 

Ist das ein Fehler? Es hat mich wirklich vermasselt, als ich versuchte, einen Suchbaum zu implementieren. Ich endete damit, (int.MinValue + 1) zu verwenden, damit ich es richtig negieren konnte.

+5

+1 Sehr interessante und lustige Frage: D – Jonathan

+1

Dies ist eines der Dinge, die ich wirklich nicht verstehe, Warum ist C# standardmäßig deaktiviert? – Aelphaeis

Antwort

57

Dies ist kein Fehler.

int.MinValue * -1 ist 1 größer als int.MaxValue kann halten. Daher wird die Nummer zurück zu int.MinValue umbrochen.

Dies wird im Wesentlichen durch einen Integer-Überlauf verursacht.

Int32.MinValue:

Der Wert dieser Konstante ist -2,147,483,648

Int32.MaxValue:

Der Wert dieser Konstante ist 2,147,483,647

So, -2,147,483,648 * -1 = 2,147,483,648 das ist 1 größer als Int32.MaxValue.

+1

Integer Mathe ist sooo Coool! ;) –

+1

@Mark, in diesem Fall finde ich es nicht cool. Es ist verwirrend. – jjnguy

+0

Hängt davon ab, wie Sie es sehen. Aus einer bitweisen Perspektive mit '-x: = ~ x + 1' und' Int32.MinValue ist '1000 0000 0000 0000 0000 0000 0000 0000' es ist eigentlich ziemlich plausibel. Und die "32" in "Int32" zeigt genau in diese Richtung :) – back2dos

9

Es ist kein Fehler, es ist ein Überlauf.

In two's complement Darstellung ist der Raum der darstellbaren Zahlen nicht symmetrisch. Das Gegenteil der kleinsten Ganzzahl kann nicht dargestellt werden. Die Berechnung läuft über und gibt Ihnen die gleiche Nummer wieder.

+7

für weniger als eine Sekunde, dachte ich, du würdest sagen, es ist kein Fehler, es ist ein Feature. : D – Jonathan

8
int i = -1 * int.MinValue; 

Diese kompilieren nicht einmal, wenn Sie Überprüfung deaktivieren:

error CS0220: The operation overflows at compile time in checked mode 
+0

Ich wollte nur wissen, dass der überprüfte Modus anscheinend standardmäßig deaktiviert ist. Http://msdn.microsoft.com/en-us/library/h25wtyxf.aspx – Aelphaeis

2

Nein, es ist kein Fehler. Es ist die Art der Zweierkomplement-Ganzzahlarithmetik.

Nehmen wir zum Beispiel einen vorzeichenbehafteten Byte-Wert, der zwischen -128 und 127 geht.

127(0x7f)+1 = 128(0x80). Jedoch ist 0x80 tatsächlich die binäre Darstellung von -128.

Somit ist für ein Byte, 128(0x80) = -128(0x80)

So -128(0x80) * -1 = 128(0x80) = -128(0x80)

2

Setzen Sie ein getestetes Region auf und sehen die "Bug" in Ausnahmefällen entwickeln. Oder versuchen Sie VB.NET (was, soweit ich mich erinnere, standardmäßig im Gegensatz zu C# überprüft wird).

+0

+1 für die Erwähnung des aktivierten Status. – Aelphaeis