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.
std::numeric_limits<T>::digits— number of binary digits (bits) of precision.std::numeric_limits<T>::digits10— number of base-10 digits that can be represented without change.std::numeric_limits<T>::max_digits10— maximum number of decimal digits needed to uniquely represent all values.
#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
std::numeric_limits<T>::lowest()— the lowest finite value (for floating-point types).std::numeric_limits<T>::epsilon()— the difference between 1 and the next representable value (for floating-point types).std::numeric_limits<T>::infinity()— represents positive infinity if supported.std::numeric_limits<T>::is_signed— tells whether the type is signed.
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
sizeof(T)gives the number of bytes a type occupies.std::numeric_limits<T>::digitsgives the number of binary digits of precision.digits10andmax_digits10describe decimal precision.max()andmin()give the range of values for a type.- Floating-point types provide additional properties like
lowest,epsilon, andinfinity. - Understanding limits helps avoid overflow, underflow, and precision errors.
- See full details at cppreference: std::numeric_limits .