std::numeric_limits::is_modulo
static const bool is_modulo; |
(until C++11) | |
static constexpr bool is_modulo; |
(since C++11) | |
The value of std::numeric_limits<T>::is_modulo is true for all arithmetic types T
that handle overflows with modulo arithmetic, that is, if the result of addition, subtraction, multiplication, or division of this type would fall outside the range [min(), max()], the value returned by such operation differs from the expected value by a multiple of max()-min()+1.
Standard specializations
T
|
value of std::numeric_limits<T>::is_modulo |
/* non-specialized */ | false |
bool | false |
char | implementation-defined |
signed char | implementation-defined |
unsigned char | true |
wchar_t | implementation-defined |
char16_t | implementation-defined |
char32_t | implementation-defined |
short | implementation-defined |
unsigned short | true |
int | implementation-defined |
unsigned int | true |
long | implementation-defined |
unsigned long | true |
long long | implementation-defined |
unsigned long long | true |
float | false |
double | false |
long double | false |
Notes
Although the C++11 standard still says "On most machines, this is true for signed integers.", the exact wording changed from C++03 to C++11 in such a way that the true value is no longer compatible with undefined behavior on signed integer overflow (it changed from "possible" to a strict requirement). Because of that, the implementations that rely on signed overflow being undefined (for optimization opportunities) now set is_modulo
to false
for signed integers. See for example GCC PR 22200.
The standard wording is expected to change to "is_modulo is false for signed integer types unless an implementation defines signed integer overflow to wrap" per LWG issue 2422.
Example
Demonstrates the behavior of modulo types
#include <iostream> #include <type_traits> #include <limits> template<class T> typename std::enable_if<std::numeric_limits<T>::is_modulo>::type check_overflow() { std::cout << "\nmax value is " << std::numeric_limits<T>::max() << '\n' << "min value is " << std::numeric_limits<T>::min() << '\n' << "max value + 1 is " << std::numeric_limits<T>::max()+1 << '\n'; } int main() { check_overflow<int>(); check_overflow<unsigned long>(); // check_overflow<float>(); // compile-time error, not a modulo type }
Possible output:
max value is 2147483647 min value is -2147483648 max value + 1 is -2147483648 max value is 18446744073709551615 min value is 0 max value + 1 is 0
See also
[static] |
identifies integer types (public static member constant) |
[static] |
identifies the IEC 559/IEEE 754 floating-point types (public static member constant) |
[static] |
identifies exact types (public static member constant) |