Ch2.15: Limits

What are Limits?

Every numeric type in C++ has a range of values it can represent. For example, int has a minimum and maximum value depending on the platform. The header <limits> provides a template std::numeric_limits<T> that lets you query these properties at compile time.

For full details, see the authoritative reference: cppreference: std::numeric_limits

sizeof(T) vs numeric_limits<T>

We have already learned that sizeof(T) tells us how many bytes a type occupies. But std::numeric_limits<T> goes further: it tells us how many digits of precision the type can represent.


#include <limits>
#include <cstddef>
#include <fast_io.h>

int main() {
    print("sizeof(double) = ", sizeof(double), " bytes\n"
        "digits (binary) = ", ::std::numeric_limits<double>::digits, "\n"
        "digits10 (decimal) = ", ::std::numeric_limits<double>::digits10, "\n"
        "max_digits10 (decimal) = ", ::std::numeric_limits<double>::max_digits10, "\n");
}

For example, double is usually 8 bytes (64 bits). But only 53 of those bits are used for precision (digits), which corresponds to about 15–17 decimal digits (digits10 and max_digits10).

Basic Range Example


#include <limits>
#include <cstddef>
#include <fast_io.h>

int main() {
    print("::std::size_t max = ", ::std::numeric_limits<::std::size_t>::max(), "\n"
        "::std::size_t min = ", ::std::numeric_limits<::std::size_t>::min(), "\n");
}

std::numeric_limits<T>::max() gives the largest representable value of type T. std::numeric_limits<T>::min() gives the smallest representable value. For unsigned types like ::std::size_t, min() is always 0.

Other Useful Properties

Why Limits Matter

Knowing the limits of a type helps prevent overflow and underflow errors. For example, adding 1 to std::numeric_limits<int>::max() causes overflow. For floating-point types, understanding digits, digits10, and epsilon is critical for numerical stability and precision.

Key Takeaways