Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't numeric_limits<T>::min() return the smallest value?

When I run this code:

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

I would expect to see an unpredictable result. But I get the correct answer:

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

How is this possible?

like image 829
Jonathan H Avatar asked Jul 18 '14 15:07

Jonathan H


People also ask

How do you find the minimum float value?

Wiki says this about float : The minimum positive normal value is 2^−126 ≈ 1.18 × 10^−38 and the minimum positive (denormal) value is 2^−149 ≈ 1.4 × 10^−45.

What is the max value of float in C++?

short: min: -32768 max: 32767 int: min: -2147483648 max: 2147483647 long: min: -2147483648 max: 2147483647 float: min: 1.17549e-038 max: 3.40282e+038 double: min: 2.22507e-308 max: 1.79769e+308 long double: min: 2.22507e-308 max: 1.79769e+308 unsigned short: min: 0 max: 65535 unsigned int: min: 0 max: 4294967295 ...


2 Answers

Because min gives you the smallest normalized value. You can still have smaller denormalized values (see http://en.wikipedia.org/wiki/Denormalized_number).

like image 63
Oliver Charlesworth Avatar answered Sep 28 '22 13:09

Oliver Charlesworth


Historical reasons. std::numeric_limits was originally built around the contents of <limits.h> (where you have e.g. INT_MIN) and <float.h> (where you have e.g. DBL_MIN). These two files were (I suspect) designed by different people; people doing floating point don't need a separate most positive and most negative value, because the most negative is always the negation of the most positive, but they do need to know the smallest value greater than 0. Regretfully, the values have the same pattern for the name, and std::numeric_limits ended up defining the semantics of min differently depending on std::numeric_limits<>::is_integer.

This makes template programming more awkward, you keep having to do things like std::numeric_limits<T>::is_integer ? std::numeric_limits<T>::min() : -std::numeric_limits<T>::max() so C++11 adds std::numeric_limits<>::lowest(), which does exactly what you'd expect.

like image 45
James Kanze Avatar answered Sep 28 '22 12:09

James Kanze