Integer overflow
-
Hallo!
Folgendes Problem:
Bei der Fakultätenrechnung kommt es schnell zu einem integer overflow.
Wie ist es möglich zu prüfungen, ob ein integer overflow stattgefunden hat? ich möchte, dass wenn ein overflow stattgefunden hat, die berechnung gestopt wird und eine fehlermeldung ausgegeben wird. ich muss leider mit dem datentyp integer arbeiten....
ich verlange keine lösung, lediglich nen kleinen denkanstoß
danke!
mfg dennis
-
Eine Möglichkeit wäre das Ergebnis jeder Multiplikation zu prüfen, ala so:
template <class T> T checked_multiply(T a, T b) { T x = a * b; if ((x / a) != b) throw whatever("integer overflow."); return x; }
-
Wird bei einem Overflow nicht automatisch eine Exception ausgelöst?
-
D schrieb:
Wird bei einem Overflow nicht automatisch eine Exception ausgelöst?
schon
-
Dann kann man doch einfach einen Exception-Handle einbauen.
-
XP^ schrieb:
D schrieb:
Wird bei einem Overflow nicht automatisch eine Exception ausgelöst?
schon
Nein, bei einem normalen Integer-Überlauf (bzw. Unterlauf) wird KEINE Exception ausgelöst:
int x=0; while(true) x++; // Endlos-Schleife
-
D schrieb:
Wird bei einem Overflow nicht automatisch eine Exception ausgelöst?
Nein. Überlauf von vorzeichenbehafteten Integern ist undefiniertes Verhalten - ein Exception (In diesem Forum heißt das immer: C++-Exception, über plattformabhängige Mechanismen brauchen wir hier nicht diskutieren) kann prinzipiell nicht geworfen werden, denn Eceptions entstehen immer nur als Resultat von Funktionsaufrufen bzw. einem throw-Ausdruck - niemals aber als Folge von eingebauten Operatoren (das wäre u.a. im Hinblick auf die unspezifizierte Reihenfolge der Auswertung von Operanden auch nur schwer zu beherrschen). Ein Überlauf vorzeichenloser Integer ist unproblematisch, da dieser modulo-2^n Arithmetik benutzen - das stellt keinen Fehler dar und löst erst recht keine Exception aus.
Folglich ist der einzig standardkonforme Weg (für vorzeichenbehaftete Integer), den Überlauf abzufangen, bevor er ensteht:template <class T> T checked_multiply(T a, T b) { return a == 0 || std::numeric_limits<T>::max() / a >= b ? a * b : throw whatever("integer overflow."); }
-
Ups, den Fall a == 0 hab ich übersehen. Peinlich ...

p.S.:
@camper: Meinst du damit meine Lösung ist (ausgenommen mal vom fehlenden Test auf a == 0) falsch? Wenn ja würde mich interessieren wo es da ein Problem geben könnte...