Spec-Zone.ru › C++

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 для целых типов со знаком,
если переполнение целых типов со знаком определено как обнуление
  1. Определение — "сумма двух положительных чисел может иметь результат, который зацикливается на третьем числе, которое меньше". У него есть следующие проблемы:
    • Он не определяет обернутое значение.
    • Он не указывает, будет ли результат воспроизводимым.
    • Он не требует, чтобы операции сложения, вычитания и других операций над всеми значениями имели определенное поведение.

См. также

is_integer
[static]
идентифицирует целые типы
(постоянная публичного статического члена)
is_iec559
[static]
идентифицирует типы с плавающей точкой IEC 559/IEEE 754
(постоянная публичного статического члена)
is_exact
[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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API