Kleinste Doublezahl?



  • Ich wundere mich gerade über die Ausgabe des folgenden Programms:

    #include <iostream>
    #include <limits>
    using namespace std;
    
    int main()
    {
    	numeric_limits<double> d;
    	cout<<d.min()<<endl;             // 2.22507e-308
    	cout<<1.0/2.0*d.min()<<endl;     // 1.11254e-308
    }
    

    ich dachte d.min() liefert mir die kleinste darstellbare Zahl...?



  • Vertexwahn schrieb:

    ich dachte d.min() liefert mir die kleinste darstellbare Zahl...?

    tut es wahrscheinlich auch. Es kommt darauf an, was man unter 'darstellbare Zahl' - und gemeint ist hier ein double - versteht.

    Mal das Testprogramm etwas aufgebohrt:

    #include <iostream>
    #include <cassert>
    #include <limits>
    
    int main()
    {
        using namespace std;
        double d = numeric_limits<double>::min();
        double eps1 = 1.0 + numeric_limits< double >::epsilon();
        assert( eps1 != 1.0 );
        double delta = d * eps1 - d;
        assert( delta != 0.0 );
        delta = (d/2)*eps1 - d/2;
        if( delta == 0.0 )
            cout << "numeric_limits<double>::min()/2 ist zu ungenau!" << endl;
        return 0;
    }
    

    Daran kann man erkennen, dass numeric_limits<double>::min() noch ein double-Wert ist, der noch mit der üblichen 'double-Genauigkeit' versehen ist. Wohingegen es bei numeric_limits<double>::min()/2 keine Rolle mehr spielt, ob man es mit einer Zahl multipliziert, die wenig größer als 1 ist (eps1).

    Falls Du einen entsprechenden Debugger hast (z.B. im VC8) so wirst Du hinter der Darstellung des Wertes von d/2 oder einer anderen kleineren Zahl als d den Zusatz #DEN stehen sehen. Soweit ich weiß steht das für 'denormalised'. Das heißt diese Zahl ist nur deshalb kleiner als min(), weil man bei der Mantisse auf Stellen - und damit auf die Genauigkeit verzichtet. Das alles dürfte in dem IEEE Standard 754 geregelt sein. Siehe auch <http://steve.hollasch.net/cgindex/coding/ieeefloat.html>.

    Gruß
    Werner


Anmelden zum Antworten