2014-07-18 15 views
6

Quando faccio funzionare questo codice:Perché numeric_limits <T> :: min() restituisce il valore più piccolo?

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

mi aspetterei di vedere un risultato imprevedibile. Ma ho la risposta corretta:

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

Come è possibile?

+0

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

+0

@crhis Grazie, era ovvio ma non ho mai fatto questa distinzione tra normalizzato/denormalizzato .. Imparando ogni giorno, credo un altro link utile è: http://en.cppreference.com/w/cpp/types/numeric_limits/denorm_min – Sheljohn

risposta

11

Perché min ti dà il più piccolo normalizzato valore. È ancora possibile avere più piccolo denormalizzato valori (vedi http://en.wikipedia.org/wiki/Denormalized_number).

+0

sto solo aspettando un altro 7 minuti per segnare questa come la risposta, vi ringrazio per la vostra risposta rapida :) – Sheljohn

+0

di Certo, questo non spiega perché la semantica di 'std :: numeric_limits <> :: min()' sia differente per il punto mobile e per i tipi interi. –

+0

@JamesKanze: Mi piace la tua risposta ora cancellata, c'è qualche possibilità di non recuperare? – GManNickG

6

ragioni storiche. std::numeric_limits è stato originariamente costruito attorno il contenuto del <limits.h> (dove si ha per esempio INT_MIN) e <float.h> (dove si ha per esempio DBL_MIN). Questi due file erano (sospetto) progettati da persone diverse; le persone che fanno virgola mobile non hanno bisogno di un valore più positivo separato e negativo, perché il più negativo è sempre la negazione del più positivo, ma hanno bisogno di conoscere il valore più piccolo di maggiore di 0. Sfortunatamente, il valori hanno lo stesso modello per il nome, e std::numeric_limits finito definire la semantica di min diverso a seconda std::numeric_limits<>::is_integer.

Questo rende la programmazione modello più imbarazzante, si continua a dover fare le cose come std::numeric_limits<T>::is_integer ? std::numeric_limits<T>::min() : -std::numeric_limits<T>::max() modo C++ 11 aggiunge std::numeric_limits<>::lowest(), che fa esattamente quello che ci si aspetterebbe.

Problemi correlati