Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Roundto rundet 3.38375 auf 3.3837 ab. Wieso?


JWI - Mi 26.01.05 13:05
Titel: Roundto rundet 3.38375 auf 3.3837 ab. Wieso?
Habe ein kleines Problem mit der Rundung


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
a:extended;
b:extended;

DecimalSeparator:='.';
SetRoundMode(rmnearest);
a:=roundto(b,-4);

Ich möchte also das der Wert in b nach a mit 4 Nachkommastellen gerundet wird.

Wenn b = 3.38375 ist das Ergebnis 3.3837
wenn b = 3.38376 ist das Ergebnis 3.3838


Frage : Müsste nicht bereits ab dem Wert 5 aufgerundet werden ?

Wenn ich SetRoundMode auf "rmup" setze wird immer aufgerundet ( 3.38374 ergibt dann 3.3838 )

Was mache ich falsch ?


Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt.
Moderiert von user profile iconTino: Titel geändert.


jasocul - Mi 26.01.05 13:18

Ich habe Delphi 5 Pro. Dort gibt es die Funktion RoundTo nicht.

Ist das vielleicht eine selbstgeschriebene Funktion? Dann ist der Fehler vielleicht dort zu suchen.


patrick - Mi 26.01.05 13:26

nein, roundto ist in der unit math
aber roundto verwendet ein anderes rechenverfahren zum runden, als du es gewöhnt bist :D
und zwar rundet nach dem bank-verfahren: genau in der mitte der zahlen 0..10 also bei 5 wird noch abgerundet

wenn du SimpleRoundTo verwendest, wird "korrekt" (arithmetisch) gerundet.


AXMD - Mi 26.01.05 13:26

jasocul hat folgendes geschrieben:
Ich habe Delphi 5 Pro. Dort gibt es die Funktion RoundTo nicht.

Ist das vielleicht eine selbstgeschriebene Funktion? Dann ist der Fehler vielleicht dort zu suchen.


Kann mir nicht vorstellen, dass es die Funktion in D5 nicht geben soll. Vielleicht hast du einfach nur vergessen, die Unit Math einzubinden.

@JWI: RoundTo rundet in der Tat etwas seltsam:

OH hat folgendes geschrieben:
RoundTo(1.235, -2) [zu] 1.24
RoundTo(1.245, -2) [zu] 1.24
:gruebel:

Ich schreib mir solche Funktionen meist selbst. Ist auch nicht schwer

AXMD


patrick - Mi 26.01.05 13:27

erster :tongue:


jasocul - Mi 26.01.05 13:31

Die Unit Math, war das erste, was ich mir angesehen habe. Dort kann ich RoundTo beim besten willen nicht finden. Komme jetzt ein wenig ins grübeln. :gruebel:


patrick - Mi 26.01.05 13:42

kommt da auch ne meldung:
Zitat:

Diese Software ist Shareware. Bitte registrieren sie sich um den vollen Produktumfang freizuschalten
:rofl: :shock:
aber scherz bei seite: round hast du doch zumindest oder?


jasocul - Mi 26.01.05 13:54

Round habe ich. Aber das steht auch nicht in "Math".
Wenn ich es richtig sehe, habt D6. Ich denke daran liegt das wohl.
Abgesehen davon arbeite ich auschließlich nur mit Raubkopien. Ich gebe doch kein Geld für etwas aus, das ich klauen kann. 8) (Bevor das jemand ernst nimmt: Hey, das sollte ironisch sein)


JWI - Mi 26.01.05 14:43

Ich bedanke mich für die prompte Antwort.

Leider rundet der "simpleroundto" auch nicht kaufmännisch.
Das Ergebnis ist identisch mit dem "roundto"

Ich habe Delphi 7 Professional im Einsatz.

Könnte es sein, dass noch eine Prozedur benutzt werden muss ?


patrick - Mi 26.01.05 20:36

ich habe es mit D6 PE getestet.
entweder habe ich die zeile zuvor übersehen oder sie war davor noch nicht da (editiert?):

Delphi-Quelltext
1:
SetRoundMode(rmnearest);                    

egal. das ist aber das problem warum die funktion
SimpleRoundTo
nicht korrekt funktioniert.
ändere den parameter in
SetRoundMode(rmTruncate);
dann dürfteste du einen unterschied sehen.
hier eine bisschen code zum testen und achzuvollziehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
  a:Extended;
  b:Extended;
  c:Extended;
begin
  b:=0.12345;
  DecimalSeparator:='.';
  SetRoundMode(rmTruncate);
  a:=RoundTo(b,-4);
  c:=SimpleRoundTo (b,-4);
  MessageDlg( 'RoundTo: '+FloatToStr(a)+#13+#10+
              'SimpleRoundTo: '+FloatToStr(c), mtInformation, [mbOK], 0);

nicht vergessen die unit Math einzubinden.


JWI - Do 27.01.05 08:34

Dies war die Lösung, vielen Dank


unsigned - Do 24.02.05 04:22


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
uses
math;
function SimpleRound(const AValue: Double; const ADigit: TRoundToRange = -2): Double;
var
  LFactor: Double;
begin
  LFactor := IntPower(10, ADigit);
  Result := trunc(((AValue+0.51*LFactor) / LFactor) ) * LFactor;
end;