Zu dem Thema Ungenauigkeit von Fließkommazahlen:
hier und
hier
Zitat von
JayK:
Und .net weigert sich decimal nach double (oder wars umgekehrt
) zu konvertieren.
Convert.ToDouble bzw.
Convert.ToDecimal
Zitat:
Zitat von
Khabarakh:
Zitat:
Für meine Zwecke reicht es auch erstmal zu ermitteln, ob die Zahl überhaupt welche hat, oder eine ganze Zahl ist.
Das bestimmst du am besten auch nur näherungsweise:
Code:
public static bool IsInteger(double D)
{
const Double Epsilon = 1e-6d;
return D - Math.Floor(D) < Epsilon;
}
Ich könnte das jetzt einfach Copy&Pasten, aber dann weiß ich überhaupt nicht, was in meinem Code vor sich geht
Wieso sollte man Ganzzahlen "nährungsweise" von anderen rationalen Zahlen unterscheiden?
Code:
double Value = 0.0d;
for (int i = 1; i <= 100; i++)
Value += 0.01d;
Console.WriteLine(Math.Floor(Value) == Value);
Fließkommazahlen kannst du einfach nicht direkt vergleichen, da es eben z.B. 1 == 1.00000001 oder 1 == 0.999999 heißt. Hier nochmal mein Code, etwas ausführlicher:
Code:
public static bool IsInteger(double D)
{
Das ist dir hoffentlich klar
.
Code:
const Double Epsilon = 1e-6d;
Das ist die größte Abweichung, die D von seinem Ganzzahlwert haben darf, dieser Wert wird in der Mathematik mit "Epsilon" bezeichnet ("Sei Epsilon größer Null...").
Code:
return Math.Abs(D - Math.Round(D)) < Epsilon;
Hier gleich eine Verbesserung, hab gestern nur an 1.000001 gedacht
.
Das gerundete D wird von D abgezogen, im oberen Beispiel wäre das dann -0.0000001 bzw. 0.0000001.
Der Betrag dieser Subtraktion muss nun kleiner als Epsilon sein, damit wir ihn als "ziemlich Ganzzahl" durchlassen.