Difference between revisions of "Round/de"

From Free Pascal wiki
Jump to navigationJump to search
(Floor, Ceil, Klarstellung bei SetRoundMode)
Line 70: Line 70:
 
* <code>[[Floor|floor(x)]]</code> (unit [[math]]): rundet zur nächstkleineren ganzen Zahl ("Floor" = "Fußboden" = "nach unten")
 
* <code>[[Floor|floor(x)]]</code> (unit [[math]]): rundet zur nächstkleineren ganzen Zahl ("Floor" = "Fußboden" = "nach unten")
  
'''Beispiele''' - man beachte die Unterschiede vor allem bei negativen Zahlen:
+
'''Beispiele''' - Man beachte die Unterschiede vor allem bei negativen Zahlen:
<syntaxhighlight>  round(1.8) = 2    round(-1.8) = -2
+
<syntaxhighlight>   
  trunc(1.8 = 1    trunc(-1.8) = -1
+
round( 1.8) // ->  2     
  ceil(1.8) = 2    ceil(-1.8) = -1
+
round(-1.8) // -> -2
  floor(1.8) = 1    floor(-1.8) = -2
+
trunc( 1.8) // ->  1     
 +
trunc(-1.8) // -> -1
 +
ceil( 1.8) // ->  2     
 +
ceil(-1.8) // -> -1
 +
floor( 1.8) // ->  1     
 +
floor(-1.8) // -> -2
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Revision as of 16:59, 31 May 2018

Template:Translate

Rundet eine Fliesskommazahl auf eine Ganzzahl.

Round

Deklaration

function Round(x: Float): Longint;

Beispiel

Code

var
  i: Integer;
begin
  WriteLn( Round(8.7) );
  WriteLn( Round(8.3) );
  // Beispiele für "Banker-Runden" - .5 wird auf die nächste gerade Zahl eingestellt
  WriteLn( Round(2.5) );
  WriteLn( Round(3.5) );

  i := Round(12.50); // Rundet ab
  WriteLn(i);
  i := Round(12.51); // Rundet auf
  WriteLn(i);
end.

Ausgabe

9
8
2
4
12
13

Banker-Runden

Die Funktion Round verwendet das Banker-Runden und rundet daher bei 0,5 zur nächsten geraden Zahl. Daher ist die Wahrscheinlichkeit für Auf- und Ab- runden bei Zufallszahlen exakt 50:50.

Es eignet sich sehr gut für statistische oder finanzmathematische Anwendungen. Bei grafischen Anwendungen – zum Beispiel beim Zeichnen von Bildern – ist das nicht immer von Vorteil. Hierdurch zeichnet folgendes Beispiel keine durchgehende, sondern eine gepunktete Linie.

Code:

var
  i: integer;
  x: single = 0.5;
begin
  for i := 0 to 99 do begin
    Canvas.Pixels[Round(x), 20]:= clBlack;
    WriteLn('Input: ', x: 0: 2, '  round: ', Round(x));
    x := x + 1.0;
  end;
end;

Ausgabe

Input: 0.50  round: 0
Input: 1.50  round: 2
Input: 2.50  round: 2
Input: 3.50  round: 4
Input: 4.50  round: 4
....

Alternativen

trunc(x), ceil(x), floor(x)

  • trunc(x): schneidet die Dezimalstellen ab und übergibt die verbleibende ganze Zahl
  • ceil(x) (unit math): rundet zur nächstgrößeren ganzen Zahl ("Ceil" = "Ceiling" = "Zimmerdecke" = "nach oben")
  • floor(x) (unit math): rundet zur nächstkleineren ganzen Zahl ("Floor" = "Fußboden" = "nach unten")

Beispiele - Man beachte die Unterschiede vor allem bei negativen Zahlen:

  
round( 1.8) // ->  2    
round(-1.8) // -> -2
trunc( 1.8) // ->  1     
trunc(-1.8) // -> -1
ceil( 1.8)  // ->  2     
ceil(-1.8)  // -> -1
floor( 1.8) // ->  1    
floor(-1.8) // -> -2

SetRoundMode()
In der Unit math steht auch die Prozedur SetRoundMode(ARoundMode) zur Verfügung. Der Parameter ARoundMode = [rmNearest, rmDown, rmUp, rmTruncate] bestimmt die Art der Rundung.

Warning-icon.png

Warnung: Die Einstellung des RoundMode findet bei allen internen Gleitkomma-Rechnungen Anwendung. Sie bestimmt insbesondere, wie Zahlen, die nicht exakt als Single/Double/Extended-Werte darstellbar sind, im Rahmen der verfügbaren Bits auf die interne Darstellung zu runden sind. Daher wird die Anwendung von SetRoundMode für allgemeine Rundungszwecke nicht empfohlen.

Eigene Rundungs-Routine

Diese folgt der üblichen Konvention, dass Zahlen, die exakt zwischen Integern liegen (0.5, 1.5, 2.5 etc), betragsmäßig aufgerundet werden:

function MyRound(x: Float): Integer;
begin
  if x > 0 then
    Result := trunc(x + 0.5)
  else
    Result := -trunc(-x + 0.5)
end;

Siehe auch