ich hatte immer das Problem, dass ich eine Zahl runden wollte, aber ihre anzahl der Nachkommastellen nicht kannte.
somit sahen die Floattostr() Ausgaben immer etwas nebulös aus, oder aber die Zahl war zu stark gerundet.
Ich hab hier mal eine Funktion gebastelt.
Könntet ihr diese mal auf Herz und Nieren prüfen bitte ? Ich bin mir nicht sicher, ob ich ein Detail übersehen haben könnte.
Vielleicht fällt ja jemanden noch etwas ein um die Geschwindigkeit zu optimieren.
Wäre vielleicht etwas für die Codelib.
Man erhält für:
115,859997410327 - 115,86
100,99 - 100,99
100 - 100
101 - 101
109 - 109
100,4 - 100,4
100 - 100
126,61999511719 - 126,62
0,0099999997765 - 0,01
115,089999999776 - 115,09
99,99999997765 - 100
99,99999997765 - 100
0,99999997765 - 1
99,09999997765 - 99,1
99,0199999997765 - 99,02
99,0100001245678 - 99,01
115,860000610352 - 115,86
115,859997410327 - 115,86
115,859974103278 - 115,86
115,85074103278 - 115,85074103278
0,00999999977648258 - 0,01
115,790000915527 - 115,79
Ausgabe mit:
Delphi-Quellcode:
d := 126.61999511719;
testmemo.Lines.Add(floattostr(d) + ' - ' + floattostr(xRound(d)));
Delphi-Quellcode:
/==============================================================================
// function xRound
// rundet und findet selbständig die Anzahl der Nachkommastellen
//==============================================================================
Function xRound (aValue : Extended) : extended;
Const
cMaxDigits = 12;
cCount = 2;
// anzahl des auftretens von Ziffer 9 oder 0 (z.B. 99 oder 00)
var Count9 : Integer;
// der count von 99 oder 00 hintereinander
Count0 : Integer;
Check9 : Boolean;
// 99 war da
check0 : boolean;
// 00 war da
Zahl : Int64;
Ziffer : Integer;
NachkommaStellen : integer;
Teiler : Extended;
Begin
Count9 := 0;
count0 := 0;
check0 := false;
check9 := false;
Nachkommastellen := cMaxDigits;
Zahl := round(Power(10,cMaxDigits) * Frac (aValue));
/// 0.0099999997765 => 99999997765
While (Zahl>0)
do begin
Ziffer := Zahl
mod 10;
if Ziffer = 0
then inc(Count0)
else if Ziffer = 9
then inc(Count9)
else begin
count0 := 0;
count9 := 0;
end;
// else
if not check9
and (count0 >= cCount)
then check0 := true;
// nicht auf check0 stellen, wenn schon check9
if not check0
and (count9 >= cCount)
then check9 := true;
if check9
then if (Ziffer <> 9)
then break;
if check0
then if (Ziffer <> 0)
then break;
Zahl := Zahl
div 10;
// von hinten abschneiden
dec(Nachkommastellen);
end;
// While Zahl > =
if not (check0
or check9)
then nachkommastellen := cMaxDigits;
Teiler := power(10, Nachkommastellen);
result := round(aValue * Teiler) / Teiler;
End;
// xRound
//==============================================================================
Phantasie ist etwas, was sich manche Leute gar nicht vorstellen können.