std::numeric_limits<T>::is_modulo
static const bool is_modulo; | (до C++11) | |
static constexpr bool is_modulo; | (начиная с C++11) |
Значение std::numeric_limits<T>::is_modulo равно true для всех арифметических типов T, которые обрабатывают переполнения с помощью модульной арифметики, то есть если результат сложения, вычитания, умножения или деления значений этого типа выходит за пределы диапазона [min(), max()], значение, возвращаемое такой операцией, отличается от ожидаемого значения на величину, кратную max() - min() + 1.
is_modulo равно false для знаковых целочисленных типов, если только реализация не определяет, что переполнение знаковых целых чисел приводит к зацикливанию.
Стандартные специализации
T | значение std::numeric_limits<T>::is_modulo |
|---|---|
| /* non-specialized */ |
false |
| bool |
false |
| char | определяется реализацией |
| signedchar | определяется реализацией |
| unsignedchar |
true |
| wchar_t | определяется реализацией |
| char8_t (начиная с C++20) |
true |
| char16_t (начиная с C++11) |
true |
| char32_t (начиная с C++11) |
true |
| short | определяется реализацией |
| unsignedshort |
true |
| int | определяется реализацией |
| unsignedint |
true |
| long | определяется реализацией |
| unsignedlong |
true |
| longlong (C++11) | определяется реализацией |
| unsignedlonglong (C++11) |
true |
| float |
false |
| double |
false |
| longdouble |
false |
Примечания
До принятия решения по вопросу LWG 2422 в стандарте говорилось: «На большинстве машин это true для знаковых целых чисел». См. GCC PR 22200, где обсуждается связанная с этим проблема.
Пример
Демонстрация поведения типов с модульной арифметикой:
#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 << "max 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>();
std::cout << '\n';
check_overflow<unsigned long>();
// check_overflow<float>(); // compile-time error, not a modulo type
}
Возможный вывод:
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
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применён к | Поведение согласно опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 612 | C++98 | определение «обрабатывать переполнения с помощью модульной арифметики» было неудачным[1] | было предоставлено более удачное определение |
| LWG 2422 | C++98 |
is_modulo требовалось, чтобы было true длязнаковых целочисленных типов на большинстве машин | требуется, чтобы было false для знаковых целочисленных типов,если только переполнение знаковых целых чисел не определено как зацикливание |
- Определение гласит: «Сложение двух положительных чисел может привести к результату, который оборачивается до третьего числа, меньшего этих чисел». У него есть следующие недостатки:
- Не определяет значение, до которого происходит оборачивание.
- Не указывает, является ли результат повторяемым.
- Не требует, чтобы сложение, вычитание и другие операции со всеми значениями имели определённое поведение.
См. также
|
[static] | определяет целочисленные типы (общедоступная статическая константа-член) |
|
[static] | определяет типы с плавающей точкой IEC 559/IEEE 754 (общедоступная статическая константа-член) |
|
[static] | определяет точные типы (общедоступная статическая константа-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/types/numeric_limits/is_modulo