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 |
| /* неспециализированный */ | false |
| bool | false |
| char | определяется реализацией |
| signed char | определяется реализацией |
| unsigned char | true |
| wchar_t | определяется реализацией |
| char8_t (начиная с C++20) | true |
| char16_t (начиная с C++11) | true |
| char32_t (начиная с C++11) | true |
| short | определяется реализацией |
| unsigned short | true |
| int | определяется реализацией |
| unsigned int | true |
| long | определяется реализацией |
| unsigned long | true |
| long long (C++11) | определяется реализацией |
| unsigned long long (C++11) | true |
| float | false |
| double | false |
| long double | false |
Примечания
Стандарт говорил: "На большинстве машин это true для знаковых целых чисел" до принятия решения по LWG issue 2422 . См. 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++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 612 | C++98 |
определение "обработки переполнений
с помощью модульной арифметики" было неудовлетворительным [1] |
предоставлено
улучшенное определение |
| LWG 2422 | C++98 |
is_modulo
требовалось быть
true
для
знаковых целочисленных типов на большинстве машин |
требуется быть
false
для знаковых целочисленных типов
если переполнение знаковых целых чисел не определено как циклическое |
-
↑
Определение гласит: "сложение двух положительных чисел может дать результат, который переполняется и превращается в третье число, которое меньше". Оно имеет следующие проблемы:
- Оно не определяет значение при переполнении.
- Оно не указывает, является ли результат воспроизводимым.
- Оно не требует, чтобы выполнение операций сложения, вычитания и других операций со всеми значениями имело определенное поведение.
Смотрите также
|
[static]
|
идентифицирует целочисленные типы
(публичная статическая константа-член) |
|
[static]
|
идентифицирует типы с плавающей точкой IEC 559/IEEE 754
(публичная статическая константа-член) |
|
[static]
|
идентифицирует точные типы
(публичная статическая константа-член) |