Einzelnen Beitrag anzeigen

Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: Auf 2 stellen Runden

  Alt 12. Okt 2017, 11:28
Um das Ganze abzuschließen, hier sind gleich mehrere Annahmen falsch.

Beim Banker's Rounding gibt es eine weitere Regelung für den Fall 0.5.

Zusammengefasst:
  • Alle Fälle außer 0.5 verhalten sich identisch zum mathematischen Runden, welches auch in Delphi angewandt wird
  • 0.5 wird im normalen Banker's Rounding immer zur nächsten geraden Zahl gerundet
  • Alternativ wird 0.5 aufgerundet.
Folgender Code deckt genau dieses Verfahren ab, wobei der letzte Parameter für True die Rundung in Richtung gerade durchführt und bei False immer aufrundet.
Delphi-Quellcode:
function BankersRound(const aValue: Double; const aRoundTo: Integer = 2; const aApplyEvenRoundRule: Boolean = True): Double;
var
  PositiveValue,
  IsEven
    : Boolean;
  MultipliedValue,
  FracValue,
  ResolutionDirection
    : Double;
const
  DOUBLE_RESOLUTION = 1E-12;
begin
  if aValue = 0 then
    Exit(0);

  MultipliedValue := Abs(aValue) * IntPower(10, aRoundTo);
  FracValue := Frac(MultipliedValue);

  if not System.Math.SameValue(FracValue, 0.5, DOUBLE_RESOLUTION) then
    Exit(System.Math.RoundTo(aValue, 0 - aRoundTo));

  PositiveValue := aValue > 0;

  if aApplyEvenRoundRule then
  begin
    IsEven := Trunc(MultipliedValue) mod 2 = 0;

    if PositiveValue and IsEven then
      // > 0 and even
      ResolutionDirection := -1
    else if PositiveValue then
      // > 0 and odd
      ResolutionDirection := 1
    else if IsEven then
      // < 0 and even
      ResolutionDirection := 1
    else
      // < 0 and odd
      ResolutionDirection := -1
  end
  else
  begin
    if PositiveValue then
      ResolutionDirection := 1
    else
      ResolutionDirection := -1;
  end;

  Result := System.Math.RoundTo(aValue + ResolutionDirection * DOUBLE_RESOLUTION, -2);
end;
Das gesamte Beispiel inkl. Testfälle ist im Anhang.

......
Angehängte Dateien
Dateityp: dpr BankersRounding.dpr (4,1 KB, 11x aufgerufen)
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat