Difference between revisions of "Round/de"

From Lazarus wiki
Jump to navigationJump to search
 
(16 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{Round}}
+
{{LanguageBar}}
  
 
Rundet eine Fliesskommazahl auf eine Ganzzahl.
 
Rundet eine Fliesskommazahl auf eine Ganzzahl.
  
 
=Round=
 
=Round=
==Deklaration:==
 
<syntaxhighlight>function Round(X: Real): Longint;</syntaxhighlight>
 
  
==Beispiel:==
+
==Deklaration==
===Code:===
+
 
<syntaxhighlight>
+
<syntaxhighlight lang="pascal" inline>function Round(x: Float): Longint;</syntaxhighlight>
 +
 
 +
==Beispiel==
 +
 
 +
===Code===
 +
 
 +
<syntaxhighlight lang="pascal">
 
var
 
var
   i1, i2: Integer;
+
   i: Integer;
 
begin
 
begin
 
   WriteLn( Round(8.7) );
 
   WriteLn( Round(8.7) );
Line 26: Line 30:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Ausgabe:===
+
===Ausgabe===
<pre>
+
 
9
+
  9
8
+
  8
2
+
  2
4
+
  4
1
+
  12
13
+
  13
</pre>
+
 
 +
==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 &ndash; zum Beispiel beim Zeichnen von Bildern &ndash; ist das nicht immer von Vorteil. Hierdurch zeichnet folgendes Beispiel keine durchgehende, sondern eine gepunktete Linie.
  
==Gefährliche Falle==
 
Dank des Banker-Runden, zeichnet folgendes Beispiel keine durchgehende Linie, sondern eine Gepunktete.
 
 
===Code:===
 
===Code:===
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 
var
 
var
 
   i: integer;
 
   i: integer;
   x: single;
+
   x: single = 0.5;
 
begin
 
begin
  x := 0.5;
 
 
 
   for i := 0 to 99 do begin
 
   for i := 0 to 99 do begin
     Canvas.Pixels[round(x), 20]:= $00;
+
     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 54: Line 60:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===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==
 +
 
 +
=== trunc(x), ceil(x), floor(x) ===
 +
 
 +
* <code>[[Trunc|trunc(x)]]</code>: schneidet die Dezimalstellen ab und übergibt die verbleibende ganze Zahl
 +
* <code>[[Ceil|ceil(x)]]</code> (unit [[math]]): rundet zur nächstgrößeren ganzen Zahl ("Ceil" = "Ceiling" = "Zimmerdecke" = "nach oben")
 +
* <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:
 +
 
 +
<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==
  
See also:
 
 
* [[Int]]
 
* [[Int]]
 
* [[Trunc]]
 
* [[Trunc]]
 
* [[Div]]
 
* [[Div]]
 +
* [[User Changes 2.2.4#Floating_point_rounding|Änderungen in FPC 2.2.4]] Fehlerkorrekur für nicht-x86 und nicht-linux/ppc64 Systeme
  
 
[[Category:Pascal/de]]
 
[[Category:Pascal/de]]

Latest revision as of 09: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