Hi stoxx, ich hab nix vor, finde Dein Problem aber interessant!
Wenn man im Dezimalsystem abrunden will, teilt man einfach durch die entsprechende Zehnerpotenz und entfernt alle Nachkommastellen.
Wenn man aufrunden will, addiert man vorher einen Wert von 9/10 der Zehnerpotenz.
Das kaufmännische Runden unterscheidet sich hier nur dadurch, dass vor der Division nicht 9/10 sondern die Hälfte der Zehnerpotenz addiert wird.
Möchte man für die Rundung jetzt Schrittweiten (S) wie 0,25 oder 0,5 verwenden, so formt man die zu rundende Zahl vor der Rundung durch eine Division durch S um, so dass wieder mit Schrittweiten von 10 gearbeitet werden kann. Dann rundet man wie oben beschrieben (Aufrunden, Abrunden oder kaufmännisch runden) und macht die Umformung durch die Multiplikation mit S wieder rückgängig.
Kommen Werte aus der
API, so können sie mit dieser Methode erst einmal "in Form" gebracht werden. Dabei ist es natürlich notwendig, dass die minimale Schrittweite bekannt ist.
Für die Übergabe an die
API müssen die Werte dann eventuell wieder durch 1.000.000 geteilt werden.
Jetzt endlich zu Deinem ursprünglichen Problem:
Ich denke mal, dass Du als minimale Schrittweite jeweils eine Zahl übergeben bekommst, die eigentlich nicht kleiner sein kann als 0,000001 und wohl nicht mehr als 4 signifikante Ziffern enthält, oder ?
Die Darstellungsgenauigkeit einer Single müsste also eigentlich vollkommen ausreichend sein um diese Zahl darstellen zu können.
Wenn eine solche Zahl in ihrer dezimalen Darstellung eine Reihe von Neunen enthält heißt das, dass die interne (binäre Darstellung) knapp unterhalb des tatsächlichen (korrekten) Wertes liegt.
Entscheidend für die Korrektur dieser Zahl auf einen "vernünftigen" Wert ist folgende Überlegung:
Die Stellen vor dem Komma benötigen zu ihrer binären Darstellung eine bestimmte Anzahl von Bits. Zahlen zwischen 64 und 127 belegen zum Beispiel alle 7 Bits, die Zahlen zwischen 128 und 255 benötigen 8 Bits usw. Diese Bits gehen für die Darstellung des Dezimalbruches verloren.
Da eine Single Floating Point Variable in Delphi für die interne Darstellung der Mantisse 23 Bit benutzt, kann man sich die Anzahl der für den Binärbruch verfügbaren Bits jeweils ausrechnen.
Nur Zahlen die kleiner als 8 sind können hier noch mit 6 Nachkommastellen dargestellt werden.
Für 4 Nachkommastellen muss die Zahl kleiner als 512 sein. Zahlen kleiner als 65536 erlauben noch 2 Nachkommastellen.
Man kann jetzt in Abhängigkeit der Größe einer Zahl entscheiden ob auf 2, 4 oder 6 Nachkomma-stellen aufgerundet werden muss. Dafür sind nur wenige Vergleiche notwendig.
Alle anderen Werte, die Du durch die
API übergeben bekommst, dürften dann also Kurswerte oder so was darstellen. Hier kennst Du ja die minimale Schrittweite und kannst die Werte wie oben beschrieben anpassen.
Hab das ganze mal mit einigen Beispielen versehen und noch ausführlicher beschrieben als Anhang beigefügt.