Hi Stoxx,
hab leider jetzt erst Zeit gehabt!
Zitat:
... da ich Platz sparen muss und ich deswegen die Zahlen auf 32 Bit "komprimiert" habe.
Dass Du Probleme mit dem Platz hattest hab ich nicht realisiert. Dein Spezialformat ist da schon genau das Richtige für die externe Speicherung.
Beim Umwandeln in Double für die internen Berechnungen kriegst Du dann aber wieder Binärbrüche mit den entsprechenden Rundungsfehlern weil der Exponent beim Floating Point Format eben die Basis 2 hat und nicht die Basis 10 (bzw. 100) wie bei Deinem Spezialformat.
Deswegen meine ich nach wie vor, dass es besser wäre, wenn du wenigstens bei allen internen Berechnungen nur
ganze Zahlen benutzt, egal ob als Double oder als Int64. In Deiner Funktion
SmallToDouble musst Du dafür einfach nur die Faktoren entsprechend ändern, ändert nix an der Laufzeit.
Die kleinste darstellbare Einheit wäre dann eben ein 10.000stel Cent (entspricht 6 Dezimalstellen) und Du könntest alle weiteren Probleme mit Rundungsfehlern und Hin- und Zurückwandeln vergessen! Bei Multiplikationen bzw. Divisionen mußt du dann, wie schon früher gesagt, die Anzahl der gedachten Nachkommastellen "zu Fuß" nachhalten. Ist aber trivial.
Die Int64 Darstellung hätte den Vorteil, dass alle Berechnungen sehr schnell gehen und außerdem sind die darstellbaren Beträge größer, weil ja der Platz für den Exponenten nicht benötigt wird.
Zitat:
... Was natürlich richtig ist, (weiß nicht, ob Du das gemeint hast) .. man könnte die minimale Preisdifferenz, wenn man sie erhält, zum Beispiel 0,249999999 selbst versuchen erstmal auf 0,25 zu runden (Anhand der Größe an sich dieser Zahl). Um dann damit wieder den eigentlichen Preis zu runden.
Hab ich so gemeint. Geht sauschnell und ist immer (!) korrekt. Die Preise, die Du über die
API erhältst kannst Du damit dann exakt darstellen.
Zitat:
... Für alle Fälle wo ich aber wiederum nur die Zahl an sich kenne ( nicht die 0,25 ) macht sich das Verfahren sehr gut.
Also "die Zahl an sich" , wenn sie als ganze Zahl dargestellt wird (siehe oben), hat niemals Darstellungsfehler und muss daher auch nie korrigiert werden.
Wenn Du aber eine Floating Point Zahl hast, die Bruchteile (also Binärbrüche) enthält, ist mein Verfahren zur Korrektur genau so anwendbar!
Für jede benutzte Mantissenlänge in Bit (Single, Real48, Double, Extended) gibt es eindeutige Grenzwerte für die jeweils möglichen dezimalen Nachkommastellen, nach dem schlichten Motto: "Je mehr Bits vor dem Komma stehen, um so weniger Bits stehen für den Binärbruch zur Verfügung".
Dein Verfahren mit der Untersuchung eines Strings ist zwar sehr trickreich und wird auch mit der schnellen Assembler-Routine von Amateurprofi für Dich brauchbar sein, hat aber zwei Nachteile:
1. Das von mir dargestellte Verfahren zur Korrektur von Darstellungsfehlern auf Grund von Binärbrüchen mit endlicher Genauigkeit dürfte um einige Größenordnungen schneller sein, selbst wenn es nicht in Assembler kodiert wird.
High speed Idee: Der Exponent der Floating Point Variablen (Bei Single = 8 Bit) kann als Index für einen Array mit der jeweiligen Anzahl von darstellbaren Nachkommastellen verwendet werden.
2. Ich fürchte, dass sich nicht beweisen lässt, dass Dein Verfahren in jedem Fall ein richtiges Ergebnis erzeugt, oder?
Zitat:
... warum machst Du das runden so kompliziert und addierst erst noch 9/10 ?
round(wert / 0.25) * 0.25 bringt die mir gewünschten Ergebnisse.
Also die
9/10 addiere ich nur dann, wenn ich
Aufrunden will,
wenn ich
abrunden will addiere ich
nix,
und wenn ich
kaufmännisch runden will addiere ich
5/10 ( Vulgo die Hälfte )
danach schneide ich die nicht benötigten Stellen ab !
Bei Integer geht das mit einem "
div" Operator, simpler geht’s nicht.
Bei Floating Point nimmst Du dann eben die Funktion
Int() in Verbindung mit dem "
/" Operator
Die Funktion
Round rundet aber weder
auf noch
ab noch
kaufmännisch, sondern macht ein
Bankers Rounding, eine Abart des kaufmännischen Rundens. Wird für Dich auch in den meisten Fällen funktionieren .... aber:
Wenn Du das hier mal aufmerksam liest ...
http://www.dsdt.info/tipps/?id=624
http://www.delphipraxis.net/internal_redirect.php?t=35275
http://www.delphipraxis.net/internal_redirect.php?t=41935
http://www.witwib.com/de:Rundung
http://www.merlyn.demon.co.uk/pas-chop.htm
... verstehst Du bestimmt warum ich doch lieber die Kontrolle selbst behalte und reproduzierbare Ergebnisse der Benutzung der Round Funktion vorziehe.
Wünsch' einen schönen Sonntag!