# std::numeric_limits<T>::is_modulo

From cppreference.com
< cpp‎ | types‎ | numeric limits

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 are possible to (until C++11)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.

`is_modulo` is false for signed integer types, unless the implementation defines signed integer overflow to wrap. | (since C++11)

### 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
char8_t | true
char16_t | true
char32_t | true
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.", it is a defect and has been corrected. 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. 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.

### Example

Demonstrates the behavior of modulo types

Run this code

    #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

### Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR | Applied to | Behavior as published | Correct behavior
--- | --- | --- | ---
LWG 2422 | C++11 | `is_modulo` was required to `true` for signed integer types on most machines | required to be false for signed integer types unless signed integer overflow is defined to wrap

### See also

is_integer [static] | identifies integer types (public static member constant)
is_iec559 [static] | identifies the IEC 559/IEEE 754 floating-point types (public static member constant)
is_exact [static] | identifies exact types (public static member constant)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/types/numeric_limits/is_modulo&oldid=108357"