Namespaces
Variants

std::saturating_add

От ru.cppreference.net
 
 
 
 
Определено в заголовке <numeric>
template< class T >
constexpr T saturating_add( T x, T y ) noexcept;
(начиная с C++26)

Вычисляет насыщающее сложение x + y. Эта операция (в отличие от встроенных арифметических операций над целыми числами) ведёт себя так, как если бы она была математической операцией с бесконечным диапазоном. Пусть q обозначает результат такой операции. Возвращает:

  • q, если q представим как значение типа T. В противном случае
  • наибольшее или наименьшее значение типа T, которое ближе к q.

Эта перегрузка участвует в разрешении перегрузки только если T является целочисленным типом, то есть: signed char, short, int, long, long long, расширенным знаковым целочисленным типом или беззнаковой версией таких типов. В частности, T не должен быть (возможно cv-квалифицированным) bool, char, wchar_t, char8_t, char16_t и char32_t, поскольку эти типы не предназначены для арифметики.

Параметры

x, y - целочисленные значения

Возвращаемое значение

Насыщенное x + y.

Примечания

В отличие от встроенных арифметических операторов над целыми числами, целочисленное продвижение не применяется к аргументам x и y.

Если переданы два аргумента разных типов, вызов не компилируется, т.е. поведение относительно вывода шаблонных аргументов такое же, как для std::min или std::max.

Большинство современных аппаратных архитектур имеют эффективную поддержку арифметики насыщения для SIMD-векторов, включая SSE2 для x86 и NEON для ARM.

Макрос тестирования возможности Значение Станд. Возможность
__cpp_lib_saturation_arithmetic 202311L (C++26) Арифметика насыщения
202603L (C++26) Переименование функций арифметики насыщения

Возможная реализация

См. libstdc++ (GCC), libc++ (Clang).

Пример

Можно просмотреть на Compiler Explorer.

#include <climits>
#include <limits>
#include <numeric>

static_assert(CHAR_BIT == 8);
static_assert(UCHAR_MAX == 255);

int main()
{
    constexpr int a = std::saturating_add(3, 4); // no saturation occurs, T = int
    static_assert(a == 7);

    constexpr unsigned char b = std::saturating_add<unsigned char>(UCHAR_MAX, 4); // saturated
    static_assert(b == UCHAR_MAX);

    constexpr unsigned char c = std::saturating_add(UCHAR_MAX, 4); // not saturated, T = int
        // saturating_add(int, int) returns int tmp == 259,
        // then assignment truncates 259 % 256 == 3 (might yield int -> unsigned char warning)
    static_assert(c == 3);

//  unsigned char d = std::saturating_add(252, c); // Error: inconsistent deductions for T

    constexpr unsigned char e = std::saturating_add<unsigned char>(251, a); // saturated
    static_assert(e == UCHAR_MAX);
        // 251 is of type T = unsigned char, `a` is converted to unsigned char value;
        // might yield an int -> unsigned char conversion warning for `a`

    constexpr signed char f = std::saturating_add<signed char>(-123, -3); // not saturated
    static_assert(f == -126);

    constexpr signed char g = std::saturating_add<signed char>(-123, -13); // saturated
    static_assert(g == std::numeric_limits<signed char>::min()); // g == -128
}

Смотри также

операция насыщающего вычитания двух целых чисел
(шаблон функции)
операция насыщающего умножения двух целых чисел
(шаблон функции)
операция насыщающего деления двух целых чисел
(шаблон функции)
возвращает целочисленное значение, ограниченное диапазоном другого целочисленного типа
(шаблон функции)
(C++17)
ограничивает значение между парой граничных значений
(шаблон функции & объект функции алгоритма)
(C++20)
проверяет, находится ли целочисленное значение в диапазоне данного целочисленного типа
(шаблон функции)
[static]
возвращает наименьшее конечное значение данного не-вещественного типа, или наименьшее положительное нормальное значение данного вещественного типа
(открытая статическая функция-элемент класса std::numeric_limits<T>)
[static]
возвращает наибольшее конечное значение данного типа
(открытая статическая функция-элемент класса std::numeric_limits<T>)

Внешние ссылки

1.  Реализация арифметики насыщения без ветвлений — Locklessinc.com, 2012