Sprache: C#
Für numerische Vergleiche von Gleitkommazahlen sollte == nicht verwendet werden. Aufgrund von der nur näherungsweisen Repräsentationen der Zahlen im Speicher ist es besser einen Vergleich mit der Maschinengenauigkeit Epsilon vorzunehmen.
D.h. statt
if (doubleWert1 == doubleWert2) sollte zur Prüfung auf Gleichheit
if (Math.Abs(doubleWert1 – doubleWert2) < epsilon)
verwendet werden.
In diesem Snippet wird gezeigt wie dieses Epsilon berechnet wird.
[u]Wichtig:[/u] Ergänzende Informationen unter http://dotnet-forum.de/forums/p/1755/6292.aspx#6292.
using System;
namespace ConsoleApplication1
{
class Program
{
private static readonly double epsilon = Epsilon();
static void Main(string[] args)
{
Console.WriteLine(epsilon);
Console.ReadKey();
}
public static double Epsilon()
{
double tau = 1.0;
double walt = 1.0;
double wneu = 0.0;
while (wneu != walt)
{
tau *= 0.5;
wneu = walt + tau;
}
return 2.0 * tau;
}
}
}
using System;
namespace ConsoleApplication1
{
class Program
{
private static readonly double epsilon = Epsilon();
static void Main(string[] args)
{
Console.WriteLine(epsilon);
Console.ReadKey();
}
public static double Epsilon()
{
double tau = 1.0;
double walt = 1.0;
double wneu = 0.0;
while (wneu != walt)
{
tau *= 0.5;
wneu = walt + tau;
}
return 2.0 * tau;
}
}
}
Alte URL:
/snippet/maschinengenauigkeit/961
Interessant, das kommt in meine Sammlung! 🙂
Ich muß mich korrigieren. Bei Epsilon hatte doch etwas in meinem Kopf geklingelt. Schau mal hier:
http://msdn.microsoft.com/de-de/library/system.double.epsilon.aspx
Alle Gleitkommazahlentypen haben Epsilon schon als Konstante im Gepäck.
Ich weiß dass all Gleitkommatypen ein Epsilon eingebaut haben. Dieses entspricht aber nicht der allgemeine numerischen Definition. Da hat sich Microsoft wohl vertan. Vergleich mal die beiden Werte.
Epsilon von mir ist 2,22044604925031E-16
Epsilon eigebatu ist 4,94065645841247E-324
Kann also in deiner Sammlung bleiben