Zahlenbereichsüberlauf



  • Guten Tag.

    Ich arbeite im Moment an einen Programm das Brüche zusammen rechnen soll. Dabei kommt es natürlich auch zu einer Multiplikation von 2 Brüchen.
    Mein Problem liegt jetzt darin einen möglichen Zahlenbereichsüberlauf zu erkennen und zu verhindern. Ich verwende als Datentyp long int für den Zähler und Nenner der Brüche. (vom Prof. so vorgeschrieben)

    Ich hoffe mir kann jemande helfen bei diesem Problem.
    Bin leider noch im absoluten Anfangsstadium in C++.

    Schonmal vielen Dank für eure Antworten.
    mfg frock 🙂



  • Dus musst das Ergebnis der Multiplikation prüfen.
    long int ist vorzeichenbehaftet, also positiv oder negativ - ein Vorzeichenwechsel zeigt den Überlauf,
    vorausgesetzt beide Faktoren haben das gleiche Vorzeichen.

    if (produkt = faktor1 * faktor2)
            printf ("Ergebnis ok");
        else
            printf ("Überlauf!");
    

    😉



  • didi2 schrieb:

    Dus musst das Ergebnis der Multiplikation prüfen.
    long int ist vorzeichenbehaftet, also positiv oder negativ - ein Vorzeichenwechsel zeigt den Überlauf,
    vorausgesetzt beide Faktoren haben das gleiche Vorzeichen.

    if (produkt = faktor1 * faktor2)
            printf ("Ergebnis ok");
        else
            printf ("Überlauf!");
    

    😉

    So natürlich:

    if ((produkt = faktor1 * faktor2) >= 0)
            printf ("Ergebnis ok");
        else
            printf ("Überlauf!");
    

    😉



  • Danke schön für den Tip!

    Ich werd das gleich mal ausprobieren. Wenn es nicht klappen sollte melde ich mich nochmal.

    mfg frock 👍



  • Das funktioniert nicht. Schließlich benutzt du vorzeichenbehaftete Ganzzahlen. Ich habe Dir hier mal eine einfache Variante als Klasse "SafeInt" geschrieben. Allerdings ist das wahrscheinlich nicht besonders effizient. Wenn Du das verbessern willst, dann lese Dir mal was zur üblichen Darstellung der Ganzzahlen mit Zweierkomplement-Speicherung durch. Du kannst die Tests mit einfachen Bitoperationen und ohne Fallunterscheidung implementieren.

    #include <iostream>
    #include <vector>
    #include <stdexcept>
    
    using namespace std;
    
    class SafeInt{
        public:
            int n;
    
            SafeInt(int number) : n(number){}
    
            SafeInt& operator*=(SafeInt other){
                if(other.n < 0 != n < 0) {
                    // Ergebnis müsste negativ sein
                    if((n = n * other.n) > 0) {
                        //Positiv, obwohl negatives Ergebnis richtig
                        throw std::overflow_error("Overflow during multiplication (1)");
                    }
                }else{
                    // Ergebnis müsste positiv sein
                    if((n = n * other.n) < 0) {
                        //Negativ, obwohl positives Ergebnis richtig
                        throw std::overflow_error("Overflow during multiplication (2)");
                    }
                }
                return *this;
            }
    };
    
    int main()
    {
        try{
            SafeInt a(5);
            SafeInt b(6);
            while(1){
                cout << "a: " << a.n << endl;
                a *= b;
            }
        }catch(std::overflow_error e){
            cout << "Error: " << e.what() << endl;
        }
    
        return 0;
    }
    

  • Administrator

    @didi,
    1. Du vergisst hier einen Fall, nämlich wenn faktor1 oder faktor2 andere Vorzeichen haben.
    2. Es ist per Standard nicht garantiert, was bei einem Overflow/Underflow passiert. Ein Betriebsystem könnte genauso gut eine Exception werfen.
    3. printf ist C, bitt verwende doch im C++ Forum die Streams, in dem Fall also std::cout .

    @frock,
    Grundsätzlich gibt es keine vernünftige Methode, ausser du prüft im voraus und stellst sicher, dass ein Over-/Underflow nicht passieren kann.

    Grüssli



  • Ich habe gute Erfahrungen mit dem SafeInt von LeBlanc gemacht. Falls dir lizenzrechtlich keine Fussfessel angelegt sind, dann würde ich den auf jeden Fall nehmen.



  • Also ich habe auch mitbekommen dass der Code von Didi3 so nicht funktiniert.
    Ich hab die Faktoren *-1 (wenn sie negativ waren) gerechnet und dann verglichen ob das Ergebniss kleiner ist als einer der beiden Faktoren.

    Bis jetzt hab ich noch keine Fehler dabei gefunden...

    Aber eure Variante werde ich mir mal genauer angucken. Leider befinde ich mich wie gesagt noch am Anfang bei der Programmierung und deswegen muss ich den Code erstmal verstehen 🙂

    Trotzdem Vielen Dank für eure Mühe.
    mfg frock 🕶


Log in to reply