![]() |
Auf 2 stellen Runden
Habe bisher mit Fox Pro gearbeitet und stehe auf dem Schlauch:
Runden: Ich will eine Zahl auf 2 Stellen runden, meine Test funktioniert nicht, es will einfach die Funktion roundto nicht akzeptieren:
Delphi-Quellcode:
Peter
var
Form1: TForm1; rech1 : single; rech2 : single; rech3 : single; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin rech1 := 8; rech2 := 9; rech3 := rech1 / rech2; label1.Caption := floattostr(roundto(rech3, -2)); end; |
Re: Auf 2 stellen Runden
Delphi ist nun mal nicht FoxPro.
Delphi-Quellcode:
function Round(e: Extended; precision: Integer): Extended;
var factor: Extended; begin factor := Power(10, precision); Result := Round(e * factor) / factor; end; |
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage |
Re: Auf 2 stellen Runden
Hallo Peter,
du mußt die Unit Math in die USES-Anweisung aufnehmen, um die Funktion RoundTo nutzen zu können. Gruß Hawkeye |
Re: Auf 2 stellen Runden
warum nimmst du nicht
Delphi-Quellcode:
Das ergibt immer zwei korrekt gerundete Nachkommastellen.
FloatToStrF(Wert, ffFixed, 8, 2);
|
Re: Auf 2 stellen Runden
Hallo Leute,
mit dem Runden habe ich so meine Probleme. Zum Beispiel wird aus 30,14500 beim runden immer 30,14000 statt 30,15000 aus 3,145 wird 3,15 aus 4,145 wird 4,14 ... zum Testen jeweils um Eins erhöht aus 31,145 wird 31,14 aus 32,145 wird 32,15 Hat jemand dafür eine Erklärung? @Hawkeye: Die Funktion RoundTo gibt es bei mir auch mit der Unit Math nicht. mfg eddy |
Re: Auf 2 stellen Runden
Ich glaube zu diesem Thema mit dem Kaufmännischen Rundungsverhalten von Delphi gabs schon mal min. einen Thread!
Versuch mal was zu finden mit der Suchfunktion! |
Re: Auf 2 stellen Runden
Zitat:
|
Re: Auf 2 stellen Runden
Zitat:
Delphi-Quellcode:
versucht?
ShowMessage(Format('%.2f', [31.145]));
|
Re: Auf 2 stellen Runden
Hallo Leute
Aufgrund Euerer Antworten ist mir plötzlich eine Lösung eingefallen, die in allen Programmiersprachen funktioniert: Klar Fox ist nicht Delphi, darum wechsle ich auch auf Delphi und verlasse das Fox, doch ich habe eine Lösung, die ich vom Fox her abgewandelt habe: Beispiel:
Delphi-Quellcode:
Und wenn wir schon dabei sind, hier meine Lösung um auf 5 zu Runden, was man in der CH braucht:
var
Form1: TForm1; rech1 : single; rech2 : single; rech3 : single; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin rech1 := 8; rech2 := 9; rech3 := rech1 / rech2; label1.Caption := floattostr(round(rech3 * 100) / 100); end;
Delphi-Quellcode:
var
Form1: TForm1; rech1 : single; rech2 : single; rech3 : single; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin rech1 := 2.75; rech2 := 55; rech3 := rech1 / rech2; label1.Caption := floattostr(round(rech3 * 20) / 20); end; Also vielen Dank für die Tipps, doch so unter uns, bin verdammt stolz, dass ich eine Lösung gefunden habe. Peter |
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. ( ![]() 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 20:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz