The numeric_limits traits is supposed to be a general way of obtaining various type infomation, to be able to do things like
template<typename T>
T min(const std::vector<T>& vect)
{
T val = std::numeric_limits<T>::min();
for(int i=0 ; i<vect.size() ; i++)
val = max(T, vect[i]);
return val;
}
The problem is that (at least using MS Visual Studio 2008) numeric_limits<int>::min() returns the smallest negative number, while numeric_limits<double>::min() returns the smallest positive number!
Anyone knows the rationalie behind this design? Is there a better (recommended?) way of using numeric_limits? In my specific function above, I could of course initialize T to vect[0], but that is not the answer I am looking for..
See also (floating-point-specific) discussion here
I'm not sure of the rationale but it is expected behaviour. Well, in the sense that is how Josuttis (and, presumably the standard) describes it!
As best I can tell if the type is not an integer (
numeric_limits<>::is_integer
) and has denormalization (numeric_limits<>::has_denorm
)min()
will return the smallest representable value by that type. Otherwise it will return the smallest value - which may be negative.For a more consistent interface check out the Boost numeric/conversion library. Specifically the
bounds
traits class. Here's a snippet:You may also find the boost::integer library useful. It brings some of C99's integer support (like
int_least16_t
) to C++ and can help select the best sized type for you particular need. An example:I often find that when I need one of boost::numeric/conversion or boost::integer I need them both.
A workaround would be
Of course, this doesn't explain the strange behaviour of numerics_limits::min() which could be a result of the fact that there are different min/max borders for integers (min = -2^n, max = 2^n-1) but not for doubles.
This is an old thread, but there is an updated answer:
C++11 added a
lowest()
function tostd::numeric_limits
(See here)So you can now call
std::numeric_limits<double>::lowest()
to get the lowest representable negative value.The definition of the smallest value for an empty vector can be argued. If the vector is empty then there is no smallest element.
Prefer to use std::min_element instead:
The behaviour of min() isn't all that strange, it returns
FLT_MIN
,DBL_MIN
orINT_MIN
(or their respective values), depending on the type you specialize with. So your question should be whyFLT_MIN
andDBL_MIN
are defined differently fromINT_MIN
.Unfortunately, I don't know the answer to that latter question.
My suspicion is that it was defined that way for practical purposes. For integer numbers, you're usually concerned with overflow/underflow, where the minimum and maximum value become of interest.
For floating point numbers, there exists a different kind of underflow in that a calculation could result in a value that's larger than zero, but smaller than the smallest representable decimal for that floating point type. Knowing that smallest representable floating point value allows you to work around the issue. See also the Wikipedia article on subnormal/denormal numbers.
numeric_limits<int>::min
returned the lowest negative number, all floating point number types, return the smallest positive number when I tried it with Sun CC & g++.I guess this is because 'smallest' and 'minimum' mean different things with floating point numbers. It is a bit odd though.
Both Sun CC and g++ produce the same result :