Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
float, double Arithmetik: Epsilon berechnen

Moderationshinweis von herbivore (21.04.2011 - 18:16:30):

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

Siassei
myCSharp.de - Member



Dabei seit:
Beiträge: 411

Themenstarter:

float, double Arithmetik: Epsilon berechnen

beantworten | zitieren | melden

Hallo,

ich muss in einem Anwendungsfall den relativen max. Fehler abschätzen.
Es werden endlich viele Grundrechenoperationen +, - , *, /, ^, .... durchgeführt. Nun soll die Stelle ermittelt werden, die im Worst-Case noch korrekt ist. Leider habe ich kein Informatik-Mathe bekommen und kann im Web keine Informationen finden.

Kann mir jemand helfen, den Fehler abzuschätzen? Ich brauche das für meine kleine Mathe-Lib :-)
Achja, double muss nicht 64bit groß sein. Im Hintergrund durchaus 80bit oder mehr. Quelle 1

Im Forum stieß ich auf folgendes:

public static double Epsilon()
        {
            double tau = 1.0;
            double alt = 1.0;
            double neu = 0.0;

            while (neu != alt)
            {
                tau *= 0.5;
                neu = alt + tau;
            }

            return 2.0 * tau;
        }
Gilt das nur für C#, oder allgemein? Somit auch für C++ native.

Gruß,
Thomas
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7538
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,
Zitat
Achja, double muss nicht 64bit groß sein.
Wenn die Programmiersprache IEEE 754 konform dann ist ein double 64bit - nicht mehr und nicht weniger.
Zitat
Gilt das nur für C#, oder allgemein? Somit auch für C++ native.
Das ist allgemein gültig - also sprachinvariant.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Siassei,
Zitat
Es werden endlich viele Grundrechenoperationen +, - , *, /, ^, .... durchgeführt.
es gibt kein festes Epsilon, das man unabhängig von der Berechnung verwenden kann. Der Fehler einer beliebigen Berechnung kann grundsätzlich beliebig groß werden. Eine Zahl minus eine fast gleichgroße Zahl mal eine sehr große Zahl führt typischerweise auch zu einem großen Fehler. Es ist also nicht mal gesagt, dass Epsilon immer kleiner eins ist.

Es gibt aber mathematische Regeln, mit denen man den (maximalen) Fehler abschätzen kann ==> Fehlerabschätzung.

herbivore
private Nachricht | Beiträge des Benutzers
Siassei
myCSharp.de - Member



Dabei seit:
Beiträge: 411

Themenstarter:

beantworten | zitieren | melden

Danke für eure Antwort :-)

@herbivore Eine manuelle Fehlerabschätzung ist natürlich möglich. Aber da wird mir der Compiler einen Strich durch die Rechnung machen. Unterschiedliche Optimierungen + Hersteller (.NET, Mono, was weiß ich) machen das so gut wie unmöglich.
Zitat
Wenn die Programmiersprache IEEE 754 konform dann ist ein double 64bit - nicht mehr und nicht weniger.
Da habe ich mich wohl falsch ausgedrückt. Nach aussen gilt dies für die meisten Sprachen. Im Hintergrund wird oftmals mit höherer Auflösung gerechnet, sofern ein Chip die nötigen Befehle besitzt.

Ich kenne nur Java in Version 1.1, wo dieses Verhalten nicht implementiert ist. Ab Version 1.2 gibt es ein Schlüsselwort, aber das kennt so gut wie keiner.
C# .NET rechnet mit einer höheren Auflösung als 64bit im Hintergrund. Ansonsten wäre das Beispiel nicht möglich.
Zitat
Epsilon von mir ist 2,22044604925031E-16
Epsilon eigebatu ist 4,94065645841247E-324
Edit: Hier wird auf die kleinste, darstellbare Zahl (von Double) runter gerechnet. Das kann nicht gut sein. Komischerweiße wird das hier im Forum empfohlen. Oder ist das ein Fall für Copy&Paste?

C++ gibt bei mir zwei identische Werte aus. (GCC 4.4.1 - Linux)
2.22045e-16 // Berechnet
2.22045e-16 // numeric_limits<double>::epsilon()
#include <iostream>
#include <limits>

using namespace std;

static double
Epsilon( )
{
    double tau = 1.0;
    double alt = 1.0;
    double neu = 0.0;

    while (neu != alt)
    {
        tau *= 0.5;
        neu = alt + tau;
    }

    return 2.0 * tau;
}


int
main(int len, char** args)
{
    cout << Epsilon( ) << endl;
    cout << numeric_limits<double>::epsilon( ) << endl;

    return 0;
}
Edit: Falschen Link
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Siassei am .
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7538
Herkunft: Waidring

beantworten | zitieren | melden

Zitat von Siassei
Zitat
Epsilon von mir ist 2,22044604925031E-16
Epsilon eigebatu ist 4,94065645841247E-324
Edit: Hier wird auf die kleinste, darstellbare Zahl (von Double) runter gerechnet. Das kann nicht gut sein. Komischerweiße wird das hier im Forum empfohlen. Oder ist das ein Fall für Copy&Paste?
Im Original wo das vorkommt (ist von mir) steht da noch mehr ;) Nämlich dass die Epsilon-Konstante der eingebauten Fließkommadatentypen bei .net nicht dem in der Numerik gebräuchlichen Epsilon (1+eps=1) entspricht sondern der kleinsten darstellbaren Fließkommazahl.
Somit ist das Zitat inkomplett.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Gelöschter Benutzer

beantworten | zitieren | melden

Zitat
C# .NET rechnet mit einer höheren Auflösung als 64bit im Hintergrund.
noe.

intel haut seine floats&doubles in den FPU, welcher mit 90 bit rechnet. das würde er aber auch in c, c++ oder java machen. amd hanhabt das ein klein wenig anders, was aber ebenfalls irrelevant sein sollte. du kannst nciht für alle möglichen arten von cpu´s eine außnahme programmieren, da du so nicht zukunftssicher programmieren kannst. gehe einfach vom worst case aus und das sind 64 bit für double, denn diese sind wenigstens garantiert.