AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Auf 2 stellen Runden

Ein Thema von Kuster Peter · begonnen am 27. Okt 2007 · letzter Beitrag vom 12. Okt 2017
Antwort Antwort
Seite 2 von 2     12
Kuster Peter

Registriert seit: 3. Apr 2007
Ort: Zürich
136 Beiträge
 
Delphi 7 Professional
 
#11

Re: Auf 2 stellen Runden

  Alt 28. Okt 2007, 17:13
Liebe Delphianer

Meine Antwort oben tönt beim Durchlesen etwas hochnäsig. Sorry, das will ich nicht, im Gegenteil, Eure Tipps sind echt gut und ich habe wieder viel gelernt, z.B. dass man Math in die Uses Anweisung einbeziehen muss etc. Alles Sachen, die mir in Zukunft helfen. Wirklich vielen Dank.

Stolz bin ich, weil ich eine Lösung gefunden habe, die einfach ist, die man ohne zusätzliche Anweisungen anwenden kann und die 100 % funktioniert und dass ich das erste Mal eine Lösung beisteuern konnte, auch wenn ich die Frage aufgeworfen habe, doch der Eddy hat das Problem auch.

Also meine Antwort nicht flasch verstehen.

Delphi gefällt mir immer besser und ich weine dem Fox bald keine Träne mehr nach!!

Ich wünsche allen eine schöne Woche.

Peter
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#12

Re: Auf 2 stellen Runden

  Alt 28. Okt 2007, 18:08
tja, für die 5 rappen rundung haste recht. aber das andere, kannst du dir sparen, das geht so..

CurrToStrF(12.355, ffFixed, 2) PS: Peter, du verwendest auch das bankers rounding. kannst mal ausprobieren:
Delphi-Quellcode:
 writeln('Round 12.5: ', round(12.5));
 writeln('Round 13.5: ', round(13.5));
denke, da kommt 'n anderes ergebnis raus, wie du gerne möchtest
  Mit Zitat antworten Zitat
Benutzerbild von eddy
eddy

Registriert seit: 4. Jan 2003
Ort: Sachsen
573 Beiträge
 
Delphi 5 Professional
 
#13

Re: Auf 2 stellen Runden

  Alt 30. Okt 2007, 12:22
Hallo Leute,

das Stichwort "bankers rounding" hat's gebracht, man muß eben wissen, wonach man suchen muß!

Allerdings kommt "bankers rounding" mit jedem Taschenrechner in Konflikt. Und auf einer Rechnung sollten die Zahlen nun mal stimmen und nicht von der Berechnung mit einem Taschenrechner abweichen. Egal welche logische oder historische Erklärung es für die Abweichung gibt.

Das mathematischen Runden liefert ein Ergebnis, das ein Taschenrechner auch her gibt.

Delphi-Quellcode:
//liefert auf nk-Stellen mathematisch gerundete Zahl r zurück
// MathRound <--> bankers rounding nur bei 0.005
function mround(r : double; nk : integer = 2) : double;
var
  diff,
  r2,
  multi: double;
begin
  r2 := abs(r);
  multi:=IntPower(10, nk); // uses Math
  diff := Frac(r * multi); // Nachkommaanteil von r
  // if diff = 0.5 versagt wg. exponentiell kleiner Abweichungen
  if round(diff * multi) / multi = 0.5
    then r2 := r2 + 0.01 / multi;
  if r >= 0
    then Result := round(r2 * multi) / multi
    else Result := -round(r2 * multi) / multi;
end;
mfg
eddy
  Mit Zitat antworten Zitat
Gorlo

Registriert seit: 6. Dez 2014
3 Beiträge
 
#14

AW: Auf 2 stellen Runden

  Alt 12. Okt 2017, 11:14
@eddy

Achtung diese Rundungsfunktion ist nicht das eine und nicht das andere. Sie funktioniert NICHT.

Sie ist bei zahlen mit mehr nachkommastellen als die auf der gerundet werden soll falsch.
Beispiel:
mround(0,014, 2) = 0,01
mround(0,01498, 2) = 0,02

PS: Ich kram diesen Thread deswegen wieder raus da er mir bei einer Suche nach Mathematischen runden in Delphi als erstes angezeigt wird und diese Funktion somit falsch verbreitet werden könnte.
  Mit Zitat antworten Zitat
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, 12: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
Gorlo

Registriert seit: 6. Dez 2014
3 Beiträge
 
#16

AW: Auf 2 stellen Runden

  Alt 12. Okt 2017, 15:45
Dazu nochmal begriff Klarstellung:
Banker's Rounding = Mathematisches Runden
Unser in der schule gelerntes Runden ist das Kaufmännische Runden.
(https://de.wikipedia.org/wiki/Rundung)

In Delphi(5-7) (andere Versionen kann ich gerade nicht nachschauen) nutzt die normale Rundungsfunktion leider das Banker's Rounding (Mathematische Runden).
Fakt ist ICH benötige das Kaufmännisches Runden (für Rechnungen (Einzelpreise 5 stellig da unter 1 Cent somit kein Currency möglich)) und das ist in Delphi(5-7) so nicht einfach möglich.
Auch aus dem Grund da die Double nicht genau genug sind.

Beispiel getestet in Delphi 6:
RoundTo(2194.825, -2) = 2194.82 | Benötigt wird aber 2194.83
Ich habe somit eine Funktion gebaut die mir den wegfallenden Dezimalwert in ein Integer umwandelt den ich dann auf 0-4 bzw. 5-9 prüfen kann. Diese Funktion prüfe ich gerade ob diese auch so funktioniert wie sie soll (was ohne Referenz schwer ist).
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz