000
13.12.2006, 01:08 Uhr
Steve06
|
Hallo,
ich programmiere in C++ und glaube, dass ich ein Präzisionsproblem habe.
Ich hole mal etwas weiter aus, um mein Problem zu beschreiben.
Folgendes lineare Gleichungssystem (LGS) mit 2 Gleichungen, 2 Unbekannen (x, y) und den Konstanten Dx, Dy, Vx, Vy ist für einen größeren Datensatz zu lösen.
1 + x * Dx + y * Dy = 0 x * Vx + y * Vy = 0
Umgeformt erhalte ich
x = - y* (Vy/Vx) y= -1/((Vy*Dx)/Vx - Dy)
So, wenn ich nun x und y für eine Datenreihe gegebener Dx,Dy,Vx,Vy berechne und zur PROBE mal die Werte wieder in die Ausgangsform des LGS oben einsetze, erhalte ich für viele, aber nicht für alle (!) Datenzeilen eine Null auf der rechten Seite der beiden Gleichungen. In ziemlich vielen Fällen erhalte ich Werte wie 5.55E-17 oder 1.67E-16. Zuerst habe ich gedacht, es muss sich um einen Programmierfehler handeln, aber dann würde doch nicht für viele das richtige (nämlich genau 0) in der Probe herauskommen?!
Ok, zugegeben, die Abweichung von der null ist schon recht gering.
Mir ist klar, dass ein Computer wegen seiner binären Struktur nicht unendlich viele Nachkommastellen speichern kann. Vermutlich ist beim Speichern der Zwischenergebnisse etwas verloren gegangen.
Ich frage Euch nun nach Möglichkeiten, das Problem zu verringern: 1. Welche Datentypen verwende ich am besten? Ich hatte zuvor double, habe aber alle beteiligten auf long double umgestellt, jedoch ohne Erfolg, d.h. ich konnte keine Veränderung feststellen! 2. Wenn man Formeln im Quellcode hinschreibt mit + - / * ( ) etc., gibt es da irgendwelche Kniffe zu beachten, damit bei den Zwischenschritten nichts verloren geht? 3. Gibt es ein paar gute alte Tricks wie z.B. einfach an irgendeinem Punkt alles mit einer großen Zahl wie 1000000000 zu multiplizieren, um die Werte nach dem Komma, die jenseits der Präzision des Datentyps liegen, "nach vorn zu holen"? 4. Gibt es eine Möglichkeit zu prüfen, ob Werte nur insignifikant von null abweichen und diese dann eben auf genau 0 zu setzen? Z.B. mal den Wert nach der 15. Nachkommastelle abschneiden und dann schauen, ob die "verstümmelte" Zahl genau 0 entspricht. Mit welchem Befehl würde man den Wert beschneiden?
Wenn mich jemand in dieser Thematik aufklären kann, bin ich sehr dankbar. Habe auch gesehen bei Google, dass es einige sog. "High oder Doubledouble Precision" Libraries für C gibt, aber ich würde gerne auf so ein Addon, dass ich als zusätzlichen Ballast empfinde, verzichten. Wenn jedoch jemand eine gute, schlanke, effiziente, unkomplizierte Library hierzu empfehlen kann, nur her damit .
Beste Grüße und danke für Euer Feedback Steve |