Namespaces
Variants

std::saturating_div

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

Вычисляет насыщающее деление x / y. Если T является знаковым целочисленным типом, x является наименьшим (наиболее отрицательным) значением T, и y == -1, возвращается наибольшее значение T; в противном случае возвращается x / y.

y не должно быть 0, иначе поведение не определено. Вызов функции не является основным константным выражением, если происходит неопределённое поведение.

Эта перегрузка участвует в разрешении перегрузки только если 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.

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

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

namespace detail {
template<class T>
concept integer =
    std::is_integral_v<T> &&
    !std::is_same_v<std::remove_cv_t<T>, bool> &&
    !std::is_same_v<std::remove_cv_t<T>, char> &&
    !std::is_same_v<std::remove_cv_t<T>, char8_t> &&
    !std::is_same_v<std::remove_cv_t<T>, char16_t> &&
    !std::is_same_v<std::remove_cv_t<T>, char32_t> &&
    !std::is_same_v<std::remove_cv_t<T>, wchar_t>;
} // namespace detail

template<detail::integer T>
constexpr T saturating_div( T x, T y ) noexcept
{
    if constexpr (std::is_signed_v<T>)
        if (x == std::numeric_limits<T>::min() && y == -1)
            return std::numeric_limits<T>::max();
    return x / y;
}

Пример

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

#include <climits>
#include <numeric>

static_assert
(""
    && (std::saturating_div<int>(6, 3) == 2) // not saturated
    && (std::saturating_div<int>(INT_MIN, -1) == INT_MAX) // saturated
    && (std::saturating_div<unsigned>(6, 3) == 2) // not saturated
);

int main() {}

См. также

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

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

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