Namespaces
Variants

std::saturating_div

De es.cppreference.net
 
 
 
 
Definido en el encabezado <numeric>
template< class T >
constexpr T saturating_div( T x, T y ) noexcept;
(desde C++26)

Calcula la saturating división x / y. Si T es un tipo entero con signo, x es el valor más pequeño (más negativo) de T, y y == -1, devuelve el valor más grande de T; de lo contrario, devuelve x / y.

y no debe ser 0, de lo contrario el comportamiento no está definido. La llamada a la función no es una expresión constante central si ocurre comportamiento no definido.

Esta sobrecarga participa en la resolución de sobrecarga solo si T es un tipo entero, es decir: signed char, short, int, long, long long, un tipo entero con signo extendido, o una versión sin signo de dichos tipos. En particular, T no debe ser (posiblemente calificado con cv) bool, char, wchar_t, char8_t, char16_t, y char32_t, ya que estos tipos no están destinados a la aritmética.

Parámetros

x, y - valores enteros

Valor de retorno

División saturada x / y.

Notas

A diferencia de los operadores aritméticos incorporados en enteros, la promoción integral no se aplica a los argumentos x y y.

Si se pasan dos argumentos de diferente tipo, la llamada falla al compilar, es decir, el comportamiento relativo a la deducción de argumentos de plantilla es el mismo que para std::min o std::max.

La mayoría de las arquitecturas de hardware modernas tienen soporte eficiente para la aritmética saturante en vectores SIMD, incluyendo SSE2 para x86 y NEON para ARM.

Feature-test macro Valor Estándar Característica
__cpp_lib_saturation_arithmetic 202311L (C++26) Aritmética saturante
202603L (C++26) Renombrar funciones de aritmética saturante

Posible implementación

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;
}

Ejemplo

Se puede previsualizar en 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() {}

Véase también

operación de suma saturante sobre dos enteros
(plantilla de función)
operación de resta saturante sobre dos enteros
(plantilla de función)
operación de multiplicación saturante sobre dos enteros
(plantilla de función)
devuelve un valor entero limitado al rango de otro tipo entero
(plantilla de función)
(C++17)
limita un valor entre un par de valores límite
(plantilla de función & objeto de función de algoritmo)
(C++20)
comprueba si un valor entero está en el rango de un tipo entero dado
(plantilla de función)
[static]
devuelve el valor finito más pequeño del tipo no flotante dado, o el valor normal positivo más pequeño del tipo flotante dado
(función miembro estática pública de std::numeric_limits<T>)
[static]
devuelve el valor finito más grande del tipo dado
(función miembro estática pública de std::numeric_limits<T>)

Enlaces externos

1.  Una implementación sin bifurcaciones de la aritmética saturante — Locklessinc.com, 2012