Hi Himitsu,
Du, ich hab mir gerade mal Deine
Unit FMath angschaut.
Die ganzen Bitmasken, die Du da gleich vordefinierst, sehen sehr effizent aus.
BitInt Erfahrung hast Du auch noch.
Vielleicht hast Du ja einen guten Tip?
wir haben einen Fixcomma64 Datentyp. Dieser hat hat feste 9 Nachkommastellen. Intern wird es als int64 Wert gespeichert.
wenn man die Zahl z.b. als Double haben möchte, muss man durch den Skalierungsfaktor teilen.
die gespeicherte Zahl ist quasi also immer um 10^9 zu groß ...
Delphi-Quellcode:
// Double
class operator FIXCOMMA64.Implicit(const AValue: FIXCOMMA64) : double;
begin
Result := AValue.FBCD9 / FBCD9EXT;
end;
Leider ist die Multiplikation um Faktor 10 langsamer als eine reine Double Multiplikation.
Am besten wäre, wir hätten eine MulDiv64 Funktion, aber die hatte ja leider damals nicht funktioniert.
Du hattest Dich auch mal dran versucht, diesen C Quelltext zu übersetzen, weiß nicht, ob Du Dich noch erinnerst.
Die Funktion ist sicher nun viel zu umständlich.
Erst wird das Ergebnis in extended ausgerechnet.
Danach der vorkomma und Nachkomma Anteil getrennt behandelt.
Der Nachkommaanteil wird dann noch gerundet.
Das erfolgt so, in dem mit einem Faktor multipliziert, der um Faktor 10 zu groß als Skalierungsfaktor selbst,
danach wird gerundet und wieder durch 10 dividiert.
das alles dient dazu, um keine Ungenauigkeiten reinzubekommen, wie bei Gleitkommazahlen üblich. funktioniert auch alles soweit.
nur eben seeehr langsam ...
iDiv64 ist aus dem Fastcode projekt ..
jetzt war meine Idee .. man würde jetzt den Exponenten auslesen. Mit einem Faktor a multiplizieren, um zu runden und durch 10 zu dividieren.
der Faktor a müsste nun die Differenz zwischen dem neuen ermitteltem Exponenten und dem Zielexponenten von 10^-9 sein, damit die Zahl als BCD Wert reingeschrieben werden kann.
Fällt Dir vielleicht etwas intelligenteres ein? Vielleicht kannst Du ja mal drüber gucken ! danke Dir schonmal !
Delphi-Quellcode:
//====[ * ]===================================================================
class operator FIXCOMMA64.Multiply(const Left, Right: FIXCOMMA64): FIXCOMMA64;
var val: extended;
begin
// FBCD9INT = 1000000000;
// FBCD9EXT = 1000000000.0;
// FBCD10INT = 10000000000;
// FBCD10EXT = 10000000000.0;
val := (Left.FBCD9 / FBCD9EXT) * (Right.FBCD9 / FBCD9EXT);
Result.FBCD9 := (Trunc(val)*FBCD9INT) + iDIV64(Round(frac(val)*FBCD10EXT), 10);
end;
Phantasie ist etwas, was sich manche Leute gar nicht vorstellen können.