den Überlauf von Integer Varaible vor Multiplikation bestimmen



  • Ich habe 2 Interger Varibale mit den Werten z.B. 0x90000000 und 0x80000000
    multipiliert man diese Variable und versucht sie als Integer zu speicher erhält man einen Überlauf. Welcher Weg ist sinnvoll und nach Möglichkeit schnell, vor der Multiplikation zu prüfen ob der Ergebniss einen Überlauf hätte?



  • ...



  • Thx. Aber ich schau als drauf, kapiers aber nicht. Könntest du mir bitte was dazusagen?

    Also INT32_MAX = 0x7fffffffL, das ist soweit klar.


  • Mod

    Hans Dampf schrieb:

    Thx. Aber ich schau als drauf, kapiers aber nicht. Könntest du mir bitte was dazusagen?

    Also INT32_MAX = 0x7fffffffL, das ist soweit klar.

    Die Idee, die Bitmapper hier hat, ist, dass das Ergebnis nicht größer werden soll als INT32_MAX, also der maximale Wert für eine 32-Bit Ganzzahl. Dazu teilt er eben diesen Wert durch einen der beiden Faktoren und vergleicht das Ergebnis mit dem anderen. Wenn das Ergebnis kleiner ist, dann würde eine Multiplikation der beiden Faktoren logischerweise auch kleiner sein als INT32_MAX, also kein Überlauf auftreten.

    Bloß ist das eben nicht logischerweise so! Wenn einer der Faktoren negativ ist, funktioniert es nicht. Wenn der Faktor 0 ist, stürzt das Programm ab. Und was Bitmapper sich von dem (double) erhofft, kann wohl nur er selbst erklären 😕 . Oder warum INT32_MAX anstatt INT_MAX. Daher: Weder Code, noch Idee übernehmen!

    Warum willst du überhaupt vor der Multiplikation prüfen? Mach's doch einfach nachher:

    datentyp result = factor1 * factor2;
    if (factor1 && result / factor1 != factor2)
    {
       // Ja, was denn eigentlich?
    }
    

    Wenn's unbedingt vorher getestet werden muss, kann man auch die Anzahl der Stellen zählen, die die beiden Faktoren in Binärdarstellung haben würden und daraus eine recht gute Abschätzung erhalten, ob das Ergebnis einer Multiplikation wahrscheinlich überfließen würde. Stichwort: Most significant bit.

    PS: Wenn's wirklich produktiv eingesetzt werden soll, wäre eine bessere Methode, Builtins des Compilers zu benutzen. Damit kann man wesentlich effizienter das korrekte Ergebnis erhalten, als mit den allgemeinen mathematischen Methoden, die ich beschrieben habe, denn diese Builtins können beispielsweise spezielle Hardwarefeatures ausnutzen. Liste für den GCC:
    https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
    Gibt's sicher auch für andere Compiler.



  • Da war ich wohl zu schnell, vergiss einfach was da stand 🙂

    SeppJ schrieb:

    Und was Bitmapper sich von dem (double) erhofft, kann wohl nur er selbst erklären 😕

    INT32_MAX / var1 ist wahrscheinlich keine Ganzzahl, deswegen das double.


  • Mod

    Bitmapper schrieb:

    INT32_MAX / var1 ist wahrscheinlich keine Ganzzahl, deswegen das double.

    Doch, das ist garantiert eine Ganzzahl, da es das Ergebnis einer Ganzzahldivision ist. Meintest du vielleicht

    (double) INT32_MAX / var1
    

    statt

    (double) (INT32_MAX / var1)
    

    ?
    Selbst das verstünde ich immer noch nicht, denn wenn 46745 < b gilt, dann gilt auch 46745.4373753 < b, wenn b eine Ganzzahl ist.

    Ich sollte noch zu meinem Beitrag nachtragen, dass ein oberschlauer Compiler die Abfrage im Code

    datentyp result = factor1 * factor2;
    if (factor1 && result / factor1 != factor2)
    

    theoretisch wegoptimieren dürfte, da das Ergebnis von Überläufen undefiniert ist. Wenn man sich absolut 100% sicher sein möchte, sollte man daher vielleicht doch lieber die Bits zählen oder die Builtins benutzen.



  • SeppJ schrieb:

    Ich sollte noch zu meinem Beitrag nachtragen, dass ein oberschlauer Compiler die Abfrage im Code

    datentyp result = factor1 * factor2;
    if (factor1 && result / factor1 != factor2)
    

    theoretisch wegoptimieren dürfte, da das Ergebnis von Überläufen undefiniert ist. Wenn man sich absolut 100% sicher sein möchte, sollte man daher vielleicht doch lieber die Bits zählen oder die Builtins benutzen.

    Nach unsigned casten.



  • Schon wieder zu schnell


  • Mod

    Der echte Tim schrieb:

    SeppJ schrieb:

    Ich sollte noch zu meinem Beitrag nachtragen, dass ein oberschlauer Compiler die Abfrage im Code

    datentyp result = factor1 * factor2;
    if (factor1 && result / factor1 != factor2)
    

    theoretisch wegoptimieren dürfte, da das Ergebnis von Überläufen undefiniert ist. Wenn man sich absolut 100% sicher sein möchte, sollte man daher vielleicht doch lieber die Bits zählen oder die Builtins benutzen.

    Nach unsigned casten.

    An welcher Stelle? Ich sehe gerade nicht, wie man das machen kann, so dass einerseits der Compiler nicht "clever" sein kann, aber trotzdem noch der Overflow korrekt erkannt werden soll.


Anmelden zum Antworten