Re: Auf 2 stellen Runden
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 |
Re: Auf 2 stellen Runden
tja, für die 5 rappen rundung haste recht. aber das andere, kannst du dir sparen, das geht so..
Delphi-Quellcode:
PS: Peter, du verwendest auch das bankers rounding. kannst mal ausprobieren:
CurrToStrF(12.355, ffFixed, 2)
Delphi-Quellcode:
denke, da kommt 'n anderes ergebnis raus, wie du gerne möchtest
writeln('Round 12.5: ', round(12.5));
writeln('Round 13.5: ', round(13.5)); |
Re: Auf 2 stellen Runden
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:
mfg
//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; eddy |
AW: Auf 2 stellen Runden
@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 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. |
AW: Auf 2 stellen Runden
Liste der Anhänge anzeigen (Anzahl: 1)
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:
Delphi-Quellcode:
Das gesamte Beispiel inkl. Testfälle ist im Anhang.
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; ...:cat:... |
AW: Auf 2 stellen Runden
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.83Ich 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). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:46 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