Einzelnen Beitrag anzeigen

Benutzerbild von stoxx
stoxx

Registriert seit: 13. Aug 2003
1.111 Beiträge
 
#1

runden von 0.0099999997765

  Alt 7. Jun 2006, 16:34
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.
  Mit Zitat antworten Zitat