Benutzer:Speifensender/Ganzzahlrundung
Zur Navigation springen
Zur Suche springen
Runden auf Ganzzahlen in C# (C# >= 2.0)
[Bearbeiten | Quelltext bearbeiten]Siehe auch Rundung und en:Rounding.
using System;
using System.Collections.Generic;
namespace DummyNamespace
{
public static class Mathematics
{
/// <summary>
/// Die Strategie, wie sich der Dezimalanteil einer Zahl auf das Rundungsergebnis auswirkt.
/// Siehe auch http://en.wikipedia.org/wiki/Rounding.
/// </summary>
public enum RoundingPolicy
{
/// <summary>
/// Das Ergebnis ist der Ganzzahlteil ohne Dezimalstellen ("Truncate").
/// </summary>
TowardsZero,
/// <summary>
/// Das Ergebnis ist die größte Ganzzahl, die nicht größer als der Eingabewert ist ("Floor").
/// </summary>
Down,
/// <summary>
/// Das Ergebnis ist die kleinste Ganzzahl, die nicht kleiner als der Eingabewert ist ("Ceiling").
/// </summary>
Up,
/// <summary>
/// Das Ergebnis ist der Eingabewert, falls der Eingabewert keine Dezimalstellen hat.
/// Andernfalls ist das Ergebnis die Ganzzahl,
/// die am nächsten zu Null liegt, wobei der Eingabewert zwischen Null und dem Ergebnis liegen muss.
/// </summary>
AwayFromZero,
/// <summary>
/// Das Ergebnis ist die Ganzzahl, die am nächsten zum Eingabewert liegt.
/// Wenn der Dezimalteil des Eingabewertes gleich 1/2 ist,
/// ist das Ergebnis der Eingabewert plus 1/2 für positive Eingabewerte,
/// bzw. der Eingabewert minus 1/2 für negative Eingabewerte.
/// </summary>
ToNearest_HalfAwayFromZero,
/// <summary>
/// Das Ergebnis ist die Ganzzahl, die am nächsten zum Eingabewert liegt.
/// Wenn der Dezimalteil des Eingabewertes gleich 1/2 ist,
/// ist das Ergebnis die Gerade Zahl, die am nächsten zum Eingabewert liegt.
/// </summary>
ToNearest_HalfToEven,
/// <summary>
/// Das Ergebnis ist die Ganzzahl, die am nächsten zum Eingabewert liegt.
/// Wenn der Dezimalteil des Eingabewertes gleich 1/2 ist,
/// ist das Ergebnis der Eingabewert plus 1/2.
/// </summary>
ToNearest_HalfUp,
}
/// <summary>
/// Ermittelt den ganzzahligen Teil einer Zahl für eine bestimmte Rundungs-Strategie (<see cref="RoundingPolicy" />).
/// </summary>
/// <param name="value">Die Eingabezahl.</param>
/// <param name="roundingPolicy">Die Rundungs-Strategie.</param>
/// <returns>Der ganzzahlige Teil der Eingabezahl gemäß der Rundungs-Strategie.</returns>
public static Decimal GetRoundedInteger(Decimal value, RoundingPolicy roundingPolicy)
{
Decimal result;
switch (roundingPolicy)
{
case RoundingPolicy.Down:
{
result = Math.Floor(value);
}
break;
case RoundingPolicy.Up:
{
result = Math.Ceiling(value);
}
break;
case RoundingPolicy.AwayFromZero:
{
result = (
value >= 0 ?
Math.Ceiling(value) :
Math.Floor(value)
);
}
break;
case RoundingPolicy.TowardsZero:
{
result = Math.Truncate(value);
}
break;
case RoundingPolicy.ToNearest_HalfAwayFromZero:
{
result = Math.Round(value, MidpointRounding.AwayFromZero);
}
break;
case RoundingPolicy.ToNearest_HalfToEven:
{
result = Math.Round(value, MidpointRounding.ToEven);
}
break;
case RoundingPolicy.ToNearest_HalfUp:
{
result = (
IsHalf(value) ?
Math.Ceiling(value) :
Math.Round(value)
);
}
break;
default:
throw new NotImplementedException(roundingPolicy.ToString());
}
return result;
}
/// <summary>
/// Ermittelt, ob der vorzeichenlose Dezimalteil einer Zahl 1/2 ist.
/// </summary>
/// <param name="value">Die Eingabezahl.</param>
/// <returns>True, wenn der vorzeichenlose Dezimalteil einer Zahl 1/2 ist. Sonst false.</returns>
public static bool IsHalf(Decimal value)
{
Decimal fraction = Fraction(value);
bool result = (fraction == new Decimal(0.5));
return result;
}
/// <summary>
/// Ermittelt den vorzeichenlosen Dezimalteil einer Zahl.
/// </summary>
/// <param name="value">Die Eingabezahl.</param>
/// <returns>Der vorzeichenlose Dezimalteil.</returns>
public static Decimal Fraction(Decimal value)
{
Decimal result = Math.Abs(value - Math.Truncate(value));
return result;
}
}
public class RoundedIntegerTester
{
static void Main(string[] args)
{
List<Decimal> values = new List<decimal>();
{
//Die 0 einfügen
values.Add(0m);
//Beträge der zu testenden Zahlen (außer 0)
{
//definieren...
List<Decimal> absoluteValues = new List<Decimal>(
new Decimal[] {
0.01m, 0.5m, 0.99m,
1m, 1.01m, 1.5m, 1.99m,
2m, 2.01m, 2.5m, 2.99m,
3m, 3.01m, 3.5m, 3.99m,
4m, 4.01m
}
);
//... und einfügen
foreach (Decimal absoluteValue in absoluteValues)
{
values.Add(+absoluteValue);
values.Add(-absoluteValue);
}
}
}
values.Sort(); //zu testende Zahlen sortieren
//alle möglichen RoundingPolicies holen
Array roundingPolicies = Enum.GetValues(typeof(Mathematics.RoundingPolicy));
//LOG-Datei erstellen
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"c:\RoundedIntegerTester.log"))
{
//Trennzeichen
string separator = ";";
//Kopfzeile
{
string line = "x" + separator;
foreach (Mathematics.RoundingPolicy roundingPolicy in roundingPolicies)
{
line += roundingPolicy + separator;
}
writer.WriteLine(line);
}
//Zahlen testen
{
foreach (Decimal value in values)
{
string line = value + separator;
foreach (Mathematics.RoundingPolicy roundingPolicy in roundingPolicies)
{
//Ergebnis holen
Decimal y = Mathematics.GetRoundedInteger(value, roundingPolicy);
line += y + separator;
}
writer.WriteLine(line);
}
}
}
//Datei für MediaWiki-Tabelle erstellen
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"c:\RoundedIntegerTester.MediaWikiTable"))
{
//Tabelle
writer.WriteLine(
"{|" +
" class=" + "\"" + "wikitable" + "\""
);
{
//Kopfzeile
{
writer.WriteLine("! " + "x");
foreach (Mathematics.RoundingPolicy roundingPolicy in roundingPolicies)
{
writer.WriteLine("! " + roundingPolicy);
}
}
//Zahlen testen
{
foreach (Decimal value in values)
{
writer.WriteLine("|" + "-");
writer.WriteLine("| " + value);
foreach (Mathematics.RoundingPolicy roundingPolicy in roundingPolicies)
{
//Ergebnis holen
Decimal y = Mathematics.GetRoundedInteger(value, roundingPolicy);
writer.WriteLine("| " + y);
}
}
}
}
writer.WriteLine("|}");
}
}
}
}
Das Ergebnis der Ganzzahlrundung sollte folgende Werte haben:
x | Down | Up | AwayFromZero | TowardsZero | ToNearest_HalfAwayFromZero | ToNearest_HalfToEven | ToNearest_HalfUp |
---|---|---|---|---|---|---|---|
-4,01 | -5 | -4 | -5 | -4 | -4 | -4 | -4 |
-4 | -4 | -4 | -4 | -4 | -4 | -4 | -4 |
-3,99 | -4 | -3 | -4 | -3 | -4 | -4 | -4 |
-3,5 | -4 | -3 | -4 | -3 | -4 | -4 | -3 |
-3,01 | -4 | -3 | -4 | -3 | -3 | -3 | -3 |
-3 | -3 | -3 | -3 | -3 | -3 | -3 | -3 |
-2,99 | -3 | -2 | -3 | -2 | -3 | -3 | -3 |
-2,5 | -3 | -2 | -3 | -2 | -3 | -2 | -2 |
-2,01 | -3 | -2 | -3 | -2 | -2 | -2 | -2 |
-2 | -2 | -2 | -2 | -2 | -2 | -2 | -2 |
-1,99 | -2 | -1 | -2 | -1 | -2 | -2 | -2 |
-1,5 | -2 | -1 | -2 | -1 | -2 | -2 | -1 |
-1,01 | -2 | -1 | -2 | -1 | -1 | -1 | -1 |
-1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 |
-0,99 | -1 | 0 | -1 | 0 | -1 | -1 | -1 |
-0,5 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
-0,01 | -1 | 0 | -1 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0,01 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
0,5 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |
0,99 | 0 | 1 | 1 | 0 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
1,01 | 1 | 2 | 2 | 1 | 1 | 1 | 1 |
1,5 | 1 | 2 | 2 | 1 | 2 | 2 | 2 |
1,99 | 1 | 2 | 2 | 1 | 2 | 2 | 2 |
2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
2,01 | 2 | 3 | 3 | 2 | 2 | 2 | 2 |
2,5 | 2 | 3 | 3 | 2 | 3 | 2 | 3 |
2,99 | 2 | 3 | 3 | 2 | 3 | 3 | 3 |
3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
3,01 | 3 | 4 | 4 | 3 | 3 | 3 | 3 |
3,5 | 3 | 4 | 4 | 3 | 4 | 4 | 4 |
3,99 | 3 | 4 | 4 | 3 | 4 | 4 | 4 |
4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
4,01 | 4 | 5 | 5 | 4 | 4 | 4 | 4 |