Och Leute - seid ihr alle durch JavaScript und PHP soweit vom Blech abgehoben, dass ihr die Grundlagen nicht mehr kennt?
So grundlegend ist das nicht, du liegst auch teilweise daneben. Im übrigen ist zumindest JS Arithmetik IEEE konform.
Sicher, in C ist die Reihenfolge der Operandenauswertung undefiniert
Das stimmt nicht. C verwendet eine left-most, inner-most Auswertungsstrategie für arithmetische Operatoren.
aber die Reihenfolge, in der die OPERATOREN angewendet werden, ist durch die Assoziativität bestimmt und deswegen erfolgt die Addition in Zeile 21 von links nach rechts.
Das stimmt nun wieder, aber das bedeutet nicht, dass die Addition auch dem Assoziativitätsgesetz folgt. Wir benutzen hier „Assoziativität“ für zwei unterschiedliche Sachverhalte, das sollten wir nicht durcheinander werfen.
Deswegen sind die Summanden x2 und x4 nach der Zuweisung an die Akkumulatorvariable
float y
verschwunden.
Das stimmt ebenfalls, das ist der Auslöschungseffekt. Es erklärt aber nicht, wieso der Fehler in der einen Berechnung auftritt und in der anderen nicht. Jedenfalls nicht, wenn man davon ausgeht, dass das Ergebnis einer Floating-Point-Addition wieder eine Floating-Point-Zahl ist.
Meine Vermutung war deshalb, dass mit einer Optimierungsstufe kompiliert wurde, die es dem Compiler erlaubt die Reihenfolge der Additions-Anwendungen zu variieren. Dann könnte aus a + b + c
nämlich c + b + a
geworden sein. Dann könnte in der einen Berechnung Auslöschung auftreten und in der anderen nicht. Deshalb kam ich auf die Nicht-Assoziativität.
Wirft man meine Annahme über Board, könnte man den Effekt auch damit erklären, dass C intern mit höherer Präzision rechnet. Darauf wolltest du vermutlich hinaus. Im Moment erscheint mir beides gleich wahrscheinlich.