- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.4k
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";