2010-06-08 14 views
5

Ich weiß, Int32.MaxValue * Int32.MaxValue wird eine Zahl größer als Int32 ergeben; Aber sollte diese Aussage nicht zu einer Ausnahme führen?Warum ist Int32.MaxValue * Int32.MaxValue == 1?

Ich lief über diese wenn etwas wie IF (X * Y > Z) wo alle sind Int32. X und Y sind ausreichend groß, Sie erhalten einen falschen Wert von X * Y.

Warum ist das so und wie kann man das umgehen? neben dem Casting alles zu Int64.

+0

Ist das in einem 'unchecked' Block? – Skywalker

+0

Siehe http://stackoverflow.com/questions/2363838/when-must-we-use-checked-operator-in-c –

Antwort

6

Sie haben die Überlauf-Überprüfungen in Ihrem Projekt deaktiviert. Mit aktiviertem Modus wird eine Ausnahme ausgelöst.

+0

danke für Ihre Antworten! Ich habe die Überlaufprüfung nicht deaktiviert; Wo ist diese Einstellung in Visual Studio? –

+0

Ich habe keine Kopie von VS hier, aber wenn ich mich gut erinnere, ist es in den erweiterten Compiler-Optionen (Rechtsklick auf ein Projekt und dann Eigenschaften -> Build -> Advanced) – munissor

19

Standardmäßig erfolgt die C# -Arithmetik in einem ungeprüften Kontext, was bedeutet, dass die Werte sich überschneiden.

Sie können das checked and unchecked keywords verwenden, um dieses Verhalten zu steuern.

+0

Gerade lief in einem Szenario, in dem int.maxvalue + 1 war int.minvalue ...Ich kratzte mich so heftig mit dem Kopf, bis ich merkte, dass er sich überrollen musste! – richard

6

Sie müssen danach fragen:

checked { 
    int a = int.MaxValue; 
    int b = int.MaxValue; 
    int c = a * b; // kaboom 
} 
26

Da int32 Grenzen um die Ergebnisse zu 32bits.

Also, wenn Sie einen Blick auf die Mathematik auf Byte-Ebene haben.

FFFFFFFF * FFFFFFFF = FFFFFFFE00000001 

Wie Sie sehen können, werden die untersten 4 Bytes = 1

2

Int32.MaxValue (mit dem angegebenen Wert here) ist 2.147.483.647.

In der Basis 2, das heißt: 111 1111 1111 1111 1111 1111 1111 1111 ... 2^31-1. Das erste Bit ist das Vorzeichenbit.

Wenn Sie multiplizieren Sie diese mit sich selbst, erhalten Sie: 11 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0001

zurück zum ursprünglichen Problem von Going „warum ist es 1?“, Da Integer.MaxValue ist der Maximalwert, die einen Integer-Überlauf verursacht. Das Ergebnis wird auf die niedrigsten 31 Bits gekürzt, die alle 0 plus 1 sind.

Edit: Hier ist a tutorial auf binäre Multiplikation. einen einfachen Fall aller 1s Mit: * 111

Sie erhalten: + 11100 = 100001

Sie können dies für den Fall Int32.MaxValue erweitern. Ich habe es zur Verkürzung auf 3 Ziffern verkürzt.

Auch, wie eine andere Antwort sagte, in C# werden diese Überläufe standardmäßig auftreten.

+0

Eine gute Behandlung für Tausend, die es brauchen, aber Das OP fragte sich, warum C# es nicht verstanden und einen Fehler geworfen hat. – BCS

8

Es ist interessant festzustellen, dass dies funktioniert unabhängig von der Basis, die Sie verwenden:

(n-1)*(n-1) mod n 
n^2 - 2n + 1 mod n 
0 - 0 + 1 mod n 
      1 mod n 
Verwandte Themen