In welcher Reihenfolge wird v = q * p * q.conjugate(); ausgewertet?
-
In welcher Reihenfolge wird der Ausdruck v = q * p * q.conjugate(); ausgewertet?
Wie ich es gerne hätte:
1. q * p;
2. q.conjugate()
3. (q*p) * (q.conjugate())Wie es anscheinend passiert:
1. q.conjugate()
2. ...Was pasiert in welcher Reihenfolge - wird erst q * p mulipliziert - oder erst p * q.conjugate()
welche Varianten sind nach C++ Standard möglich
Das Problem ist, das q.conjugate den Wert von q ändert. Und die Berechnung so ablaufen sollte: q_orginal_wert * p * q_veränderter_wert
das Problem könnte aber sein, dass: q_veränderte_wert * p * q_veränderter_wert berechnet wird - und das eventuell jeder Compiler z. B. der gcc anders wie Visual Studio macht
-
Imho ist keine Reihenfolge im C++-Standard vorgeschrieben.
Alles, was dort geschrieben steht ist die Priorität der Operatoren.Aber die Auswertungsreihenfolge ist nicht definiert.
Wenn du unbedingt eine bestimmte Reihenfolge möchtest, wirst du nicht umher kommen, die Anweisung in mehrere Anweisungen aufzusplitten.int i = 3; int j = i+=2 + i*=5;Und, welchen Wert hat j?
Richtig - kann niemand sagen - es ist einfach nicht definiert...bb
-
DerBesucher schrieb:
In welcher Reihenfolge wird der Ausdruck v = q * p * q.conjugate(); ausgewertet?
C++ schreibt keine Auswerte-Reihenfolge von Unterausdrücken vor.
DerBesucher schrieb:
Wie ich es gerne hätte:
1. q * p;
2. q.conjugate()
3. (q*p) * (q.conjugate())wäre möglich.
DerBesucher schrieb:
Wie es anscheinend passiert:
1. q.conjugate()
2. ...ist auch legal.
DerBesucher schrieb:
welche Varianten sind nach C++ Standard möglich
beides.
DerBesucher schrieb:
Das Problem ist, das q.conjugate den Wert von q ändert.

Dein Programm sollte nicht von der Auswertereihenfolge von Unterausdrücken abhängen. Das ist hier leider nicht gegeben.DerBesucher schrieb:
Und die Berechnung so ablaufen sollte: q_orginal_wert * p * q_veränderter_wert
das Problem könnte aber sein, dass: q_veränderte_wert * p * q_veränderter_wert berechnet wird - und das eventuell jeder Compiler z. B. der gcc anders wie Visual Studio machtDann musst Du das in mehrere Anweisungen zerlegen:
auto qp = q*p; q.conjugate(); auto blah = qp*q;Oder, wenn es sich um komplexe Zahlen handelt:
double squared_magnitude(mycomplex const& d) { double r = real(d); double i = imag(d); return r*r+i*i; } ... auto blah = squared_magnitude(q)*p; q.conjugate();Das sollte etwas effizienter sein.
Gibt es dann einen besonderen Grund, warum Du nicht std::complex verwendest? std::complex bietet auch eine norm-Funktion, die das ausrechnet, was ich "squared_magnitude" genannt habe.
kk
-
unskilled schrieb:
Imho ist keine Reihenfolge im C++-Standard vorgeschrieben.
Alles, was dort geschrieben steht ist die Priorität der Operatoren.Die Priorität und die Assoziativität. "=" ist Rechtsassoziativ und "" ist Linksassoziativ. Die Priorität von "." ist höher als die von "", als die von "=". Das bedeutet
DerBesucher schrieb:
v = q * p * q.conjugate(); ausgewertet?
Dass das äquivalent zu
v = ( (q * p) * (q.conjugate() ) )ist. Das sagt natürlich noch nichts darüber aus, in welcher Reihenfolge die Funktionen aufgerufen werden. Nur, dass sie in der richtigen Reihenfolge kombiniert werden.
-
Dazu muss man nur ein Ableitungsbaum aus der Grammatik erstellen.
-
Zeus schrieb:
Dazu muss man nur ein Ableitungsbaum aus der Grammatik erstellen.
Der/Ein Ableitungsbaum sagt in der Regel nichts über die Reihenfolge der Auswertung der Operatoren aus.
-
-.- nvm
-
krümelkacker schrieb:
Gibt es dann einen besonderen Grund, warum Du nicht std::complex verwendest?
Ja - ich benötige quaternions und die gibt es nicht im Namespace std
-
DerBesucher schrieb:
krümelkacker schrieb:
Gibt es dann einen besonderen Grund, warum Du nicht std::complex verwendest?
Ja - ich benötige quaternions und die gibt es nicht im Namespace std
Es gibt Boost.Quaternions. Möglicherweise ist das eine Alternative.
-
Du solltest dich auch fragen, weshalb conjugate() Setter und Getter zugleich ist. Und vielleicht eine globale Nur-Getter-Funktion anbieten, wenn es diese nicht schon gibt.