Darf der Compiler umklammern?



  • Hallo

    darf der Compiler umklammern?

    also aus
    d = a*(b/c);
    darf er das genauso auswerten wie
    d= (a*b)/c?

    Normalerweise ist das ja das gleiche, aber bei floating-points. etc. ist es das eben manchmal nicht. Kann ich den Ausdruck dann einfach so klammern wie ich möchte? Oder ist es dann sicherer in zwei Ausdrücke zu zerlegen:

    d=b/c;
    d*=a;

    MfG Jester



  • Wenn der Grad der Ungenauigkeit bei float/double von der Rechenoperation abhängt, wäre es wurscht, denke ich.



  • würde mich wundern wenn er das dürfte. Zumindest bei Klassen mit entsprechend überladenen Operatoren.



  • Jester schrieb:

    Hallo
    darf der Compiler umklammern?

    afair nein.

    schau auf die compileroptionen. da musste es eine geben, die sagt "rechne ungenau, aber schnell mit floats." ich hab zwer keine ahnung, ob das stimmt, aber ich bin immer davon ausgegangen, das sei ein umklammerungsknopf.
    normalerweise ist der knopf auf "sicher aber langsamer" eingestellt. falls du ihn verstellt hast, solltest du dich dran erinnern.



  • Normalerweise ist das ja das gleiche, aber bei floating-points. etc. ist es das eben manchmal nicht.

    Das ist doch definitiv nicht das Gleiche, bei int erst recht nicht.

    2 * (2/3) != (2 * 2)/3

    (EDIT: achso, du hast dich wahrscheinlich ausschließlich auf floats bezogen, sorry)

    IMHO darf er das auch bei floats nicht, wie du ja gesagt hast, kann das Ergebnis dort auch abweichen. Der VC++ (bei dem weiß ichs jetzt grad) kennt aber Optionen, mit denen man regeln kann, wie konform er sich da verhalten soll.



  • Bei int ist das ganze noch schlimmer:

    int a = 1000;
    int b = 2;
    int c = 5;

    a*(b/c) == 0; //true
    (a*b)/c == 400; //true

    Oder

    a = 2;
    b = std::numeric_limit<int>::max();
    c = 100;



  • @Volkard: Ich glaube, das geht weiter als nur mit Umklammern. Manche Prozessoren kennen Befehle wie Multiply-add, die multen und gleich danach was adden. Das Ergebnis wird dadurch genauer, aber der IEEE Standard schreibt vor, dass nach jeder Operation nach einem bestimmten Muster gerundet werden muss.



  • @Jester: Wäre der Fehler wirklich so dramatisch? Ich meine mich daran erinnern zu können, dass sowohl Multiplikation als auch Division numerisch ähnlich gut konditioniert sind.



  • Daß er es bei UDTs nicht darf ist klar. Mich interessieren hier vor allem eingebaute Typen. Also floats und ints.

    Aber ich denke ich kann soweit sicher sein, daß er meine Rechnungen nicht durcheinanderwirft.

    MFG Jester


Anmelden zum Antworten