2014-07-18 2 views
6

Wenn ich diesen Code ausführen:Warum nicht numeric_limits <T> :: min() den kleinsten Wert zurückgeben?

#include <limits> 
#include <cstdio> 

#define T double 

int main() 
{ 
    static const T val = std::numeric_limits<T>::min(); 
    printf("%g/2 = %g\n", val, val/2); 
} 

ich erwarten würde ein unvorhersehbares Ergebnis zu sehen. Aber ich habe die richtige Antwort:

(16:53) > clang++ test_division.cpp -o test_division 
(16:54) > ./test_division 
2.22507e-308/2 = 1.11254e-308 

Wie ist das möglich?

+0

Lesen Sie http://en.cppreference.com/w/cpp/types/numeric_limits/min – chris

+0

@crhis Danke, das war offensichtlich, aber ich habe diese Unterscheidung zwischen normalisiert/denormalized nie gemacht. Lernen jeden Tag, schätze ich Ein weiterer nützlicher Link ist: http://en.cppreference.com/w/cpp/types/numeric_limits/denorm_min – Sheljohn

Antwort

11

Da min gibt Ihnen die kleinste normalisierte Wert. Sie können immer noch kleinere denormalisierte Werte haben (siehe http://en.wikipedia.org/wiki/Denormalized_number).

+0

Ich warte nur noch 7 Minuten, um dies als die Antwort zu markieren, danke für Ihre schnelle Antwort :) – Sheljohn

+0

Of Natürlich erklärt dies nicht, warum die Semantik von 'std :: numeric_limits <> :: min()' für Fließkommazahlen und für ganzzahlige Typen unterschiedlich ist. –

+0

@JamesKanze: Ich mag Ihre jetzt gelöschte Antwort, jede Chance auf Wiederherstellung? – GManNickG

6

Historische Gründe. std::numeric_limits wurde ursprünglich um den Inhalt von <limits.h> gebaut (wo Sie z. B. INT_MIN haben) und <float.h> (wo Sie beispielsweise haben DBL_MIN). Diese zwei Dateien wurden (ich vermute) von verschiedenen Leuten entworfen; Leute, die Fließkommazahl nicht brauchen, trennen ein höchst positives und am meisten negativen Wert, weil das negativste immer die Negation des positivsten ist, aber sie müssen den kleinsten Wert wissen, der größer als 0 ist. Bedauernswerterweise Werte haben die gleichen Muster für den Namen, und std::numeric_limits endete die Definition der Semantik von min unterschiedlich je nach std::numeric_limits<>::is_integer.

Dies macht Template-Programmierung mehr umständlich, man muss immer wieder zu Dinge tun, wie std::numeric_limits<T>::is_integer ? std::numeric_limits<T>::min() : -std::numeric_limits<T>::max() so C++ 11 addiert std::numeric_limits<>::lowest(), das tut genau das, was man erwarten würde.

Verwandte Themen