Namespaces
Variants

std::saturating_div

Depuis fr.cppreference.net
 
 
 
 
Défini dans l'en-tête <numeric>
template< class T >
constexpr T saturating_div( T x, T y ) noexcept;
(depuis C++26)

Calcule la division par saturation x / y. Si T est un type entier signé, x est la valeur la plus petite (la plus négative) de T, et y == -1, retourne la plus grande valeur de T ; sinon, retourne x / y.

y ne doit pas être 0, sinon le comportement est indéfini. L'appel de fonction n'est pas une expression constante centrale si un comportement indéfini se produit.

Cette surcharge ne participe à la résolution de surcharge que si T est un type entier, c'est-à‑dire : signed char, short, int, long, long long, un type entier signé étendu, ou une version non signée de tels types. En particulier, T ne doit pas être (éventuellement qualifié cv) bool, char, wchar_t, char8_t, char16_t, et char32_t, car ces types ne sont pas destinés à l'arithmétique.

Paramètres

x, y - valeurs entières

Valeur de retour

Division par saturation x / y.

Notes

Contrairement aux opérateurs arithmétiques intégrés sur les entiers, la promotion entière ne s'applique pas aux arguments x et y.

Si deux arguments de types différents sont passés, l'appel échoue à la compilation, c'est-à‑dire que le comportement vis-à‑vis de la déduction d'argument de modèle est le même que pour std::min ou std::max.

La plupart des architectures matérielles modernes prennent en charge efficacement l'arithmétique par saturation sur vecteurs SIMD, y compris SSE2 pour x86 et NEON pour ARM.

Macro de test de fonctionnalité Valeur Norme Fonctionnalité
__cpp_lib_saturation_arithmetic 202311L (C++26) Arithmétique par saturation
202603L (C++26) Renommage des fonctions d'arithmétique par saturation

Implémentation possible

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

Exemple

Peut être prévisualisé sur 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() {}

Voir aussi

opération d'addition par saturation sur deux entiers
(modèle de fonction)
opération de soustraction par saturation sur deux entiers
(modèle de fonction)
opération de multiplication par saturation sur deux entiers
(modèle de fonction)
retourne une valeur entière limitée à l'intervalle d'un autre type entier
(modèle de fonction)
(C++17)
limite une valeur entre une paire de valeurs de borne
(modèle de fonction & objet fonction d'algorithme)
(C++20)
vérifie si une valeur entière est dans l'intervalle d'un type entier donné
(modèle de fonction)
[static]
retourne la plus petite valeur finie du type non‑virgule‑flottante donné, ou la plus petite valeur normale positive du type à virgule flottante donné
(fonction membre statique publique de std::numeric_limits<T>)
[static]
retourne la plus grande valeur finie du type donné
(fonction membre statique publique de std::numeric_limits<T>)

Liens externes

1.  Une implémentation sans branche de l'arithmétique par saturation — Locklessinc.com, 2012