2014-07-18 10 views
6

Kiedy uruchomić ten kod:Dlaczego liczbaic_limits <T> :: min() nie zwraca najmniejszej wartości?

#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); 
} 

spodziewałbym się zobaczyć nieprzewidywalne rezultaty. Ale mam prawidłową odpowiedź:

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

Jak to możliwe?

+0

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

+0

@crhis Dziękuję, to było oczywiste, ale ja nigdy się tego rozróżnienia między znormalizowane/nieznormalizowana .. Nauka na co dzień, myślę, innym przydatnym linkiem jest: http://en.cppreference.com/w/cpp/types/numeric_limits/denorm_min – Sheljohn

Odpowiedz

11

Ponieważ daje najmniejszą wartość znormalizowaną . Nadal możesz mieć mniejsze wartości zdenormalizowane (patrz http://en.wikipedia.org/wiki/Denormalized_number).

+0

Po prostu czekam kolejne 7 minut, aby oznaczyć to jako odpowiedź, dziękuję za szybką odpowiedź :) – Sheljohn

+0

Of Oczywiście to nie wyjaśnia, dlaczego semantyka 'std :: numeric_limits <> :: min()' jest różna dla zmiennoprzecinkowych i dla typów integralnych. –

+0

@JamesKanze: Podoba mi się twoja teraz usunięta odpowiedź, jakaś szansa na usunięcie? – GManNickG

6

Powody historyczne. std::numeric_limits został pierwotnie zbudowany wokół zawartości <limits.h> (gdzie masz np. INT_MIN) i <float.h> (gdzie masz np. DBL_MIN). Te dwa pliki były (jak podejrzewam) zaprojektowane przez różnych ludzi; osoby robiące zmiennoprzecinkowe nie potrzebują osobnego najbardziej pozytywnego i najbardziej ujemnej wartości, ponieważ najbardziej negatywna jest zawsze negacja najbardziej pozytywna, ale muszą znać najmniejszą wartość większą niż 0. . Z żalem wartości mają ten sam wzorzec dla nazwy, i std::numeric_limits zakończyły się definiując semantykę min inaczej w zależności od std::numeric_limits<>::is_integer.

To sprawia, że ​​programowanie szablon bardziej niewygodne, zachować konieczności robić takie rzeczy jak std::numeric_limits<T>::is_integer ? std::numeric_limits<T>::min() : -std::numeric_limits<T>::max() tak C++ 11 dodaje std::numeric_limits<>::lowest(), która robi dokładnie to, czego można się spodziewać.

Powiązane problemy