Hallo,
In einem meiner Projekte habe ich folgende Zuweisung:
Delphi-Quelltext
1:
| x := Trunc( (locX + shift) * FieldW * BufW / ( w * FullW * scale ) ); |
scale ist vom Typ Extended, ansonsten sind alles Integers.
Um das unten beschriebene Problem zu umgehen, könnte ich die hintere Klammer auflösen und die entstehenden Divisionen ggf. etwas nach vorne ziehen (vielleicht auch die vordere Klammer
(locX + shift) ausmultiplizieren). Wie gehe ich dabei vor, damit der Wert für
x möglichst Stabil ist, d.h. damit er für möglichst viele Variablenbelegungen möglichst nahe am richtigen Ergebnis liegt?
Ich nehme an, dass für Überlauf-Stabilität die Zwischenergebnisse möglichst nahe an 1 liegen sollten (Exponent), ich für Genauigkeit aber möglichst viele der Zwischenergebnisse in Integer-Typen halten will (Mantisse), korrekt?
Zwischenergebnisse nahe an 1 halten:
1:
| x := Trunc( (locX + shift) * ( FieldW / FullW ) * ( BufW / w ) / scale ) ); |
Lange in Integer bleiben:
1:
| x := Trunc( ( (locX + shift) * FieldW * BufW ) / ( ( w * FullW ) * scale ) ); |
Auch wird
hier spekuliert, dass die Zwischenergebnisse eine reduzierte Genauigkeit haben (statt einer erhöhten

)
Zum Effekt:
Obwohl alle Variablen positiv sind, ist das Ergebnis negativ
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| ( x = -144 für
locX = 507 shift = 4578 FieldW = 300 BufW = 1408 w = 1408 FullW = 1500 scale = 7,05219818923083 ) |
Wenn ich diese Werte im Quelltext für die Variablen einsetze (
x := Trunc( (507 + 4578) * 300 * 1408 / ( 1408 * 1500 * 7.05219818923083 ) );, erhalte ich vom Compiler:
Quelltext
1:
| [DCC Error] frmMain.pas(494): E2099 Overflow in conversion or arithmetic operation |
lg,
Daniel