2016-06-20 13 views
0

Ich bin ein großes Problem konfrontiert, und ich habe keine Ahnung, was es verursacht und wie diese zu beheben. Ich erstelle ein Spiel, in dem ich Objekte in Java zeichne. Zum Zeichnen verwende ich eine lineare Interpolation, die den Wert 'alpha' verwendet, um das Objekt mit einem bestimmten Zeitwert in einem Bild zu verschieben.Gleitkomma-Determinismus - Java macht falsche Ausgabe, C++ richtig

Hier ist, wie das Interpolations-Algorithmus wie folgt aussieht:

draw.x = current.getX() * alpha + previous.getX() * (1.0f - alpha); 

Alle obigen Werte sind Schwimmern (alpha, Strom, PREV und zeichnen).

Nehmen wir an, wir bewegen uns nicht und unsere current.getX() und previous.getX() sind 100.0f Floats.

Alpha-Wert ist zufällig (es ist nicht zufällig, aber es ist eine Zahl in 0.0 - 1.0 Bereich) - auch float.

des alpha = 0,4352343

draw.x = 100.f * 0.4352343 + 100.f * (1.0f - 0.4352343) == 43,52343 + 56,47657 == 100 

nehmen lassen, die perfekt ist, weil wir nicht in Bewegung sind - es 100 sein sollte (unsere bisherigen und aktuellen Positionen sind beide 100).

So funktioniert Mathe, egal welchen Wert alpha wäre - es wird immer zurück 100, Recht?

NO!

In C++ tut es - es funktioniert perfekt, ich habe es für 30 Minuten mit einer Ausgabe von 10 Millionen Fällen getestet - es gibt immer 100.0 zurück.

Aber in Java - tut es nicht. Für 80.000 Fälle gibt es ~ 400-500 Fälle, in denen draw.x (Rückgabewert von unserer Funktion) 99,999999999999 wird.

Es ist völlig inakzeptabel Ursache, wenn ich zeichne, muss ich int verwenden, so muss ich werfen, so gibt es 99 Wert und Sie können erraten, was mit der Animation passiert.

Ich habe nur eine Frage - wie dies möglich ist, dass obige Algorithmus unterschiedliche Werte in Java und C++ geben kann und wie dies zu beheben in Java?

+5

Warum in aller Welt würden Sie es anstatt Rundung werfen? – Kayaman

+0

Mit C++ ist wichtig, welche konkrete Implementierung Sie verwenden. Einige können so berechnen, einige verschiedene –

+0

Haben Sie die binären IEEE754 Darstellungen in beiden Fällen verglichen? Ich nehme an, dass sie gleich sind und dass die Laufzeitbibliotheken nur unterschiedliche Algorithmen verwenden, um den Gleitkommawert in einen String zu konvertieren, so dass Sie unterschiedliche ** Ausgänge ** erhalten. Siehe auch https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html und http://stackoverflow.com/questions/7153979/algorithm-to-convert-an-ieee-754- double-to-a-string –

Antwort

-1

Es hat mit Rundungsfehlern zu tun, auch wenn ich unsicher bin, warum sie zustande kommen. Um es zu beheben, können Sie

richtige Antwort = Math.round (Antwort) verwenden;