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