webentwicklung-frage-antwort-db.com.de

Beste Möglichkeit, Integer-Überlauf in C # zu behandeln?

Die Behandlung eines ganzzahligen Überlaufs ist eine häufige Aufgabe, aber wie können Sie in C # am besten damit umgehen? Gibt es etwas syntaktischen Zucker, um es einfacher zu machen als bei anderen Sprachen? Oder ist das wirklich der beste Weg?

int x = foo();
int test = x * common;
if(test / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");
38
Ben Lakey

Ich habe es nicht oft gebraucht, aber Sie können das Schlüsselwort checked verwenden:

int x = foo();
int test = checked(x * common);

Wird bei Überläufen zu einer Laufzeitausnahme führen. Von MSDN:

Wenn in einem überprüften Kontext ein Ausdruck einen Wert erzeugt, der .__ ist. außerhalb des Bereichs des Zieltyps hängt das Ergebnis von .__ ab. ob der Ausdruck konstant oder nicht konstant ist. Konstante Ausdrücke verursachen Fehler bei der Kompilierung, während nicht konstante Ausdrücke werden zur Laufzeit ausgewertet und lösen Ausnahmen aus.

Ich sollte auch darauf hinweisen, dass es ein anderes C # -Schlüsselwort gibt, unchecked, das natürlich das Gegenteil von checked tut und Überläufe ignoriert. Sie fragen sich vielleicht, wann Sie jemals unchecked verwenden würden, da es sich um das Standardverhalten handelt. Nun, es gibt eine C # -Compileroption, die definiert, wie Ausdrücke außerhalb von checked und unchecked behandelt werden: /checked . Sie können es unter den erweiterten Build-Einstellungen Ihres Projekts festlegen.

Wenn Sie viele Ausdrücke haben, die überprüft werden müssen, wäre es am einfachsten, die /checked build -Option zu setzen. Jeder Ausdruck, der überläuft, wenn er nicht in unchecked eingeschlossen ist, führt zu einer Laufzeitausnahme.

95
Michael Petito

Versuche Folgendes

int x = foo();
try {
  int test = checked (x * common);
  Console.WriteLine("safe!");
} catch (OverflowException) {
  Console.WriteLine("oh noes!");
}
18
JaredPar

Der beste Weg ist als Micheal Said - verwenden Sie das geprüfte Schlüsselwort .

int x = int.MaxValue;
try   
{
    checked
    {
        int test = x * 2;
        Console.WriteLine("No Overflow!");
    }
}
catch (OverflowException ex)
{
   Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}
7
Chinjoo

Manchmal ist der einfachste Weg der beste Weg. Ich kann mir keine bessere Methode vorstellen, um das zu schreiben, was Sie geschrieben haben, aber Sie können es kurz verkürzen:

int x = foo();

if ((x * common) / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");

Beachten Sie, dass ich die Variable x nicht entfernt habe, da es dumm wäre, die Funktion foo() dreimal aufzurufen.

4
Alon Gubkin

Alter Thread, aber ich bin gerade in dieses geraten. Ich wollte keine Ausnahmen verwenden. Was ich endete mit:

long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
    do whatever you want with the overflow
return((int)a);
1
YourUncleBob

Also bin ich nach dieser Tatsache weit darauf gestoßen, und es hat meine Frage größtenteils beantwortet, aber für meinen speziellen Fall (für den Fall, dass jemand andere die gleichen Anforderungen hat), wollte ich alles, was den positiven Wert eines signierten Inters überschreiten würde bei int.MaxValue abrechnen:

int x = int.MaxValue - 3;
int someval = foo();

try
{
   x += someval;
}

catch (OverflowException)
{
   x = int.MaxValue;
}
0
Jesse Williams