Wie wird in C# gerundet?

Das umwandeln von Float, Double oder Decimal in einen Integer funktioniert in C# nach der IEEE 754 Definition und ist somit nicht immer wie man es erwarten würde, wenn man nur den kaufmännischen Weg kennt. Zunächst einmal sollte erwähnt werden, dass es verschiedene Wege gibt aus einer Gleitkommazahl eine Ganzzahl zu machen. Ich werde euch hier die einzelnen Wege einmal vorstellen.

Der erste Weg, ist das direkte Umwandeln durch einen Datentyp-Cast. Hierbei werden jedoch Nachkommastellen einfach abgeschnitten statt wirklich gerundet zu werden. Dies würde wie folgt aussehen:

float myFloat = 4.8f;
int myInteger = (int)myFloat; // myInteger wird nun 4 sein.

Die nächste Möglichkeit ist das Umwandeln von Typen über die Convert-Klasse aus dem .NET-Framework.

float myFloat = 4.8f;
int myInteger = Convert.ToInt32(myFloat); // myInteger wird nun 5 sein.

Hierbei würden wir augenscheinlich zunächst das richtige Ergebnis erhalten, aber was ist, wenn unsere Zahl genau in der Mitte liegt? Hier kommt es dann zum Problem.

int myInteger1 = Convert.ToInt32(8.5); // myInteger1 wird nun 8 sein.
int myInteger2 = Convert.ToInt32(9.5); // myInteger2 wird nun 10 sein.

Um das Problem kurz aufzulösen: Hierbei wird immer zur nächsten geraden (sprich durch zwei teilbaren) Zahl gerundet. Im Falle von 8,5 also zur 8 und im Falle von 9,5 zur 10. Leider kommt es zu dem gleichen Problem, wenn man die Methode Math.Round verwendet. Es sei den, man benutzt eine Überladung für die Math.Round Methode unter der Angabe des „MidpointRounding„-Parameters. Mehr Informationen dazu gibt es hier:
https://msdn.microsoft.com/en-us/library/system.midpointrounding.aspx

Typenwandlung in C#

Um einen Typen in einen anderen zu verwandeln, gibt es in C# mehrere Wege. Zum einen gibt es das typische „Casten“, zum anderen das „Safty Casten“ und dann noch die „Convert“-Klasse. Beginnen wir mit der „Convert“-Klasse, da diese sich ein wenig von den anderen unterscheidet. Diese bietet uns statische Methoden wie „ToInt32“, um z.B. einen String in einen Integer zu wandeln. Allerdings stehen hier nur die .NET Standard-Datentypen wie Byte, Short, Integer, Long, Float, Double, Decimal, Character und String jeweils Signed und Unsigned (zumindest die Ganzzahlen) zur Verfügung. Sollte hier eine Wandlung nicht möglich sein, wird eine Ausnahme ausgelöst.

Zusätzlich gibt es auch noch das typische „Casten“, welches in nahezu jeder objektorientierten Programmiersprache möglich ist. Auch hierbei wird eine Ausnahme ausgelöst, wenn die Typenwandlung nicht möglich ist. Zusätzlich gibt es im .NET über das „as“-Keyword noch das „Safty Casten“. Dies erledigt die Typenwandlung und im Falle des unmöglichen, wird keine Ausnahme ausgelöst, sondern der Standardwert des Zieltypen hergestellt. Bedingt durch das nicht auslösen der Ausnahme empfehle ich diese Art der Typenwandlung zu vermeiden, denn es sorgt dafür, dass Fehler länger gesucht werden müssen als nötig.