2016-07-09 18 views
2

Ich habe eine Vektorklasse (2D mathematischer Vektor) mit float s als seine Komponenten.Verwenden Sie doppelt so lange wie möglich vor dem Gießen zu schweben?

Für einige Zwischenberechnungen habe ich die Wahl, Doppel zu verwenden. Soll ich die doppelte Zwischenpräzision so lange wie möglich verwenden, nur Gießen, um am Ende zu schweben, oder ist es besser, so bald wie möglich irgendwelche Doppel zu schweben?

Zum Beispiel, hier sind zwei mögliche Implementierungen der Vektornormierung.

Erstens halten die Doppel für alle Berechnungen:

public class Vector2f {  

    private float x; 
    private float y; 

    .... 

    public Vector2f normalize() { 
     double length = Math.sqrt((x * x) + (y * y)); 
     return new Vector2f(
       (float) (x/length), 
       (float) (y/length) 
     ); 
    } 
} 

Zweitens Umwandlung sofort zu schweben:

public Vector2f normalize() { 
    float length = (float) Math.sqrt((x * x) + (y * y)); 
    return new Vector2f(
      x/length, 
      y/length 
    ); 
} 
+0

Im Allgemeinen ist es immer besser, die Präzision so lange wie möglich beizubehalten, besonders wenn Ihre Werte sehr klein sind/nahe bei Null liegen. –

+0

Ich denke, es hängt von der Anwendung und den Werten ab, die Sie haben. Beachten Sie jedoch, dass die Leistung unter konstanten Conversions von Float zu Double und Back leiden kann. Sie können nur entscheiden, was für Ihre Anwendung besser ist, indem Sie beide ausprobieren und prüfen, ob die zweite Version gut genug ist. –

+1

Nicht verwandt, aber beachten Sie, dass Sie, wenn Sie weiterhin double verwenden, tun können: 'double factor = 1.0/Math.sqrt ((x * x) + (y * y)); ... neues Vector2f (x * Faktor, y * Faktor); '. –

Antwort

4

Generell ist es immer besser Präzision zu halten, so lange wie möglich, vor allem, wenn Deine Werte sind sehr klein/nahe bei Null.

Versuchen Sie diese Zeilen:

System.out.println(0.00001f * 0.00002f/0.00000003f); 
System.out.println(0.00001d * 0.00002d/0.00000003d); 

Der Ausgang wird:

0.0066666664 
0.006666666666666668 

Welche ist besser, was denken Sie? Solche Fehler können sich in Ihren Berechnungen ansammeln und Ihre Ausgabe beeinflussen.

Um es lustig zu machen:

System.out.println(0.00001f * 0.00002f * 0.00000003f* 0.00000003f* 0.00000003f* 0.00000003f* 0.00000003f * 0.00000003f/0.00000003f/0.00000003f/0.00000003f/0.00000003f/ 0.00000003f/ 0.00000003f); 
System.out.println(0.00001d * 0.00002d * 0.00000003d* 0.00000003d* 0.00000003d* 0.00000003d* 0.00000003d * 0.00000003d/0.00000003d/0.00000003d/0.00000003d/0.00000003d/ 0.00000003d/ 0.00000003d); 

und Ausgang:

0.0 
2.0000000000000003E-10 

mit kleinen Werten vorsichtig!

0

Das Ergebnis des Gießens vom Doppel zum Floaten am Ende wird genauer sein als das Gießen vor diesem Vorgang.

  x/length, 
     y/length 

Lösung eins scheint besser als andere.