Im Grunde liegt es wohl eher an Rundungsfehlern bei der Verwendung von Fließkommazahlen.
eine 0,9 könnte genau 0,9000000000 sein, aber wenn sich das nicht genau darstellen lässt oder es bei der Berechnung nicht ganz genau rauskommt,
könnte es quasi 0,899999999999 aber auch 0,9000000000001 sein. (vereinfachtes Beispiel, damit man sieht, was ich meine)
Und dann liefert es nachfolgend eben auch andere Werte,
z.B. bei Trunc oder Int(0,899999999999 * 10) eben 8 anstatt 9.
https://de.wikipedia.org/wiki/Gleitkommazahl
https://de.wikipedia.org/wiki/Doppelte_Genauigkeit
https://de.wikipedia.org/wiki/IEEE_754
...
Bei mir geht's und es sind wirklich ganz genau 0,000000. (aber muß eben nicht)
Double und Extended
Code:
type MyFloat = Double; //Extended;
procedure TForm25.FormCreate(Sender: TObject);
procedure DebugLog(Val: MyFloat);
begin
var S := string.Create(' ', SizeOf(Val) * 2);
BinToHex(@Val, PChar(S), Length(S)); // Val.Bytes[i] for 0..9
{ knallt beim zweiten Durchlauf
S := S + ' / ' + Val.ToString
+ ' / s' + Val.Sign.ToString
+ ' e' + Val.Exp.ToString
+ ' f' + Val.Frac.ToString;
+ ' / e' + Val.Exponent.ToString
+ ' f' + Val.Fraction.ToString
+ ' m' + Val.Mantissa.ToString
}
S := S + ' / ' + Val.ToString;
S := S + ' / s' + Val.Sign.ToString;
S := S + ' e' + Val.Exp.ToString;
S := S + ' f' + Val.Frac.ToString;
S := S + ' / e' + Val.Exponent.ToString;
try S := S + ' f' + Val.Fraction.ToString; except S := S + ' peng'; end; // k.A. was es gegen 1/3 hat
try S := S + ' m' + Val.Mantissa.ToString; except S := S + ' peng'; end;
OutputDebugString(PChar(S));
end;
var
Val, Frac, Frac2: MyFloat;
begin
Val := 22.649; DebugLog(Val); // A01A2FDD24A63640 / 22,649 / s0 e1027 f1871527120149152 / e4 f1,4155625 m6375126747519648
Val := Val * 100; DebugLog(Val); // CDCCCCCCCCB1A140 / 2264,9 / s0 e1034 f476968144129229 / e11 f1,105908203125 m4980567771499725
Val := System.Int(Val); DebugLog(Val); // 0000000000B0A140 / 2264 / s0 e1034 f474989023199232 / e11 f1,10546875 m4978588650569728
Frac := System.Frac(Val); DebugLog(Frac); // 0000000000000000 / 0 / s0 e0 f0 / e0 f0 m0
Frac2 := Frac * 10.0; DebugLog(Frac2); // 0000000000000000 / 0 / s0 e0 f0 / e0 f0 m0
Frac2 := System.Int(Frac2); DebugLog(Frac2); // 0000000000000000 / 0 / s0 e0 f0 / e0 f0 m0
// auch komisch:
Frac2 := Frac * 10.0; DebugLog(Frac2); // 0000000000000000 / 0 / s0 e0 f0 / e0 f0 m0
Frac2 := System.Frac(Frac2); DebugLog(Frac2); // 0000000000000000 / 0 / s0 e0 f0 / e0 f0 m0
Val := 1 / 3; DebugLog(Val); // 555555555555D53F / 0,333333333333333 / s0 e1021 f1501199875790165 / e-2 peng peng
Val := 1 / 5; DebugLog(Val); // 9A9999999999C93F / 0,2 / s0 e1020 f2702159776422298 / e-3 f1,6 m7205759403792794
end;