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] |
идентифицирует точные типы (постоянная публичного статического члена) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/types/numeric_limits/is_modulo