-
Notifications
You must be signed in to change notification settings - Fork 5.3k
std::numeric_limits
A tidbit to keep in mind about the messiness of std::numeric_limits<T>
when the T
is a floating-point type. The functions below return the values of a floating-point type T
which are:
Member function | Semantics |
---|---|
std::numeric_limits<T>::lowest() |
the smallest representable value (huge negative number). |
std::numeric_limits<T>::denorm_min() |
the smallest positive representable value (very small positive number). |
std::numeric_limits<T>::min() |
the smallest positive non-denormal number (also a very small positive number). |
std::numeric_limits<T>::max() |
the largest representable value of type T (huge positive number). |
In other words,
lowest() <= -max() < -min() <= -denorm_min() < ((T)0) < denorm_min() <= min() < max()
^[1] ^[2] ^[2]
[1] strictly less is an exotic case.
[2] strictly equal is an exotic case.
Also, for regular floats of 32, 64 and 80 bit, and, I think but not sure, for all IEEE-754[-like?] floating point numbers, lowest() == -max()
holds. But this is not guaranteed to be true for all float types. The lowest()
has been added to C++11 because of this. Also, the values of -denorm_min()
and -min()
are what you think they should be; no change here, up to an including C++20. The only exception is added for the max()
, which is, apparently, in exotic cases, does not produce the most negative representable number when negated.
For reference, the table
T |
lowest() |
denorm_min() |
min() |
max() |
---|---|---|---|---|
float | -3.40282e+38 | 1.4013e-45 | 1.17549e-38 | 3.40282e+38 |
double | -1.79769e+308 | 4.94066e-324 | 2.22507e-308 | 1.79769e+308 |
long double | -1.18973e+4932 | 3.6452e-4951 | 3.3621e-4932 | 1.18973e+4932 |
and the code to produce it, partly lifted from cppreference.com:
#include <limits>
#include <iostream>
int main()
{
std::cout << "| `T` | `lowest()` | `denorm_min()` | `min()` | `max()` |\n"
<< "| ---: | ---: | ---: | ---: | ---: |\n"
<< "| float | "
<< std::numeric_limits<float>::lowest() << " | "
<< std::numeric_limits<float>::denorm_min() << " | "
<< std::numeric_limits<float>::min() << " | "
<< std::numeric_limits<float>::max() << " |\n"
<< "| double | "
<< std::numeric_limits<double>::lowest() << " | "
<< std::numeric_limits<double>::denorm_min() << " | "
<< std::numeric_limits<double>::min() << " | "
<< std::numeric_limits<double>::max() << " |\n"
<< "| long double | "
<< std::numeric_limits<long double>::lowest() << " | "
<< std::numeric_limits<long double>::denorm_min() << " | "
<< std::numeric_limits<long double>::min() << " | "
<< std::numeric_limits<long double>::max() << " |\n";