Difference between revisions of "Round/de"

From Free Pascal wiki
Jump to navigationJump to search
 
(5 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Translate}}
+
{{LanguageBar}}
  
 
Rundet eine Fliesskommazahl auf eine Ganzzahl.
 
Rundet eine Fliesskommazahl auf eine Ganzzahl.
  
 
=Round=
 
=Round=
 +
 
==Deklaration==
 
==Deklaration==
<syntaxhighlight>function Round(X: Real): Longint;</syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal" inline>function Round(x: Float): Longint;</syntaxhighlight>
  
 
==Beispiel==
 
==Beispiel==
 +
 
===Code===
 
===Code===
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 
var
 
var
 
   i: Integer;
 
   i: Integer;
Line 27: Line 31:
  
 
===Ausgabe===
 
===Ausgabe===
<pre>
+
 
9
+
  9
8
+
  8
2
+
  2
4
+
  4
12
+
  12
13
+
  13
</pre>
 
  
 
==Banker-Runden==
 
==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.
 
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 &ndash; zum Beispiel beim Zeichnen von Bildern &ndash; ist das nicht immer von Vorteil. Hierdurch zeichnet folgendes Beispiel keine durchgehende Linie, sondern eine Gepunktete.
+
Es eignet sich sehr gut für statistische oder finanzmathematische Anwendungen. Bei grafischen Anwendungen &ndash; zum Beispiel beim Zeichnen von Bildern &ndash; ist das nicht immer von Vorteil. Hierdurch zeichnet folgendes Beispiel keine durchgehende, sondern eine gepunktete Linie.
 +
 
 
===Code:===
 
===Code:===
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 
var
 
var
 
   i: integer;
 
   i: integer;
Line 48: Line 54:
 
   for i := 0 to 99 do begin
 
   for i := 0 to 99 do begin
 
     Canvas.Pixels[Round(x), 20]:= clBlack;
 
     Canvas.Pixels[Round(x), 20]:= clBlack;
     WriteLn('Input:', x: 6: 2, ' round: ', Round(x): 4);
+
     WriteLn('Input: ', x: 0: 2, ' round: ', Round(x));
 
     x := x + 1.0;
 
     x := x + 1.0;
 
   end;
 
   end;
Line 55: Line 61:
  
 
===Ausgabe===
 
===Ausgabe===
<pre>
+
 
Input:   0.50 round:   0
+
  Input: 0.50 round: 0
Input:   1.50 round:   2
+
  Input: 1.50 round: 2
Input:   2.50 round:   2
+
  Input: 2.50 round: 2
Input:   3.50 round:   4
+
  Input: 3.50 round: 4
Input:   4.50 round:   4
+
  Input: 4.50 round: 4
....
+
  ....
</pre>
 
  
 
==Alternativen==
 
==Alternativen==
Zum Abrunden kann [[Trunc]] verwenden werden.
 
  
Mit der Prozedur [[doc:rtl/math/setroundmode.html|<code>SetRoundMode(ARoundMode)</code>]] aus der Unit [[Math]] kann der Rundungsmodus für alle folgenden Aufrufe von Round() eingestellt werden. Der Parameter <code>ARoundMode</code> kann folgende Werte annehmen:
+
=== trunc(x), ceil(x), floor(x) ===
* <code>rmNearest</code>: Rundet zum nächsten Integer, bei x.5 zum nächsten ''geraden'' Integer (Banker's Rounding)
+
 
* <code>rmDown</code>: Roundet generell zum nächstkleineren Integer
+
* <code>[[Trunc|trunc(x)]]</code>: schneidet die Dezimalstellen ab und übergibt die verbleibende ganze Zahl
* <code>rmUp</code>: Rundet generell zum nächstgrößeren Integer
+
* <code>[[Ceil|ceil(x)]]</code> (unit [[math]]): rundet zur nächstgrößeren ganzen Zahl ("Ceil" = "Ceiling" = "Zimmerdecke" = "nach oben")
* <code>rmTruncate</code>: Schneidet die Dezimalstellen ab.
+
* <code>[[Floor|floor(x)]]</code> (unit [[math]]): rundet zur nächstkleineren ganzen Zahl ("Floor" = "Fußboden" = "nach unten")
Der Unterschied zwischen <code>rmDown</code> und <code>rmTruncate</code> zeigt sich bei negativen Zahlen: Mit <code>rmDown</code> entsteht aus der Zahl -1.25 der Wert -2, während sich mit <code>rmTruncate</code> der Wert -1 ergibt.
+
 
 +
'''Beispiele''' - Man beachte die Unterschiede vor allem bei negativen Zahlen:
 +
 
 +
<syntaxhighlight lang="pascal">
 +
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
 +
</syntaxhighlight>
 +
 
 +
'''SetRoundMode()'''
 +
 
 +
In der Unit [[math]] steht auch die Prozedur [[doc:rtl/math/setroundmode.html|<syntaxhighlight lang="pascal" inline>SetRoundMode(ARoundMode)</syntaxhighlight>]] zur Verfügung. Der Parameter <syntaxhighlight lang="pascal" inline>ARoundMode = [rmNearest, rmDown, rmUp, rmTruncate]</syntaxhighlight> bestimmt die Art der Rundung.
 +
 
 +
{{Warning|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 <code>SetRoundMode</code> 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:
 +
 
 +
<syntaxhighlight lang="pascal">
 +
function MyRound(x: Float): Longint;
 +
begin
 +
  if x > 0 then
 +
    Result := trunc(x + 0.5)
 +
  else
 +
    Result := -trunc(-x + 0.5)
 +
end;
 +
</syntaxhighlight>
  
 
==Siehe auch==
 
==Siehe auch==
 +
 
* [[Int]]
 
* [[Int]]
 
* [[Trunc]]
 
* [[Trunc]]

Latest revision as of 10:50, 25 April 2020

Deutsch (de) English (en) Esperanto (eo) suomi (fi) русский (ru)

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): Longint;
begin
  if x > 0 then
    Result := trunc(x + 0.5)
  else
    Result := -trunc(-x + 0.5)
end;

Siehe auch