Namespaces
Variants

std::saturating_add

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

Calcule l'addition saturante x + y. Cette opération (contrairement aux opérations arithmétiques intégrées sur les entiers) se comporte comme si elle était une opération mathématique avec un domaine infini. Soit q le résultat d'une telle opération. Renvoie :

  • q, si q est représentable comme une valeur de type T. Sinon,
  • la plus grande ou la plus petite valeur de type T, selon celle qui est la plus proche de q.

Cette surcharge participe à la résolution de surcharge seulement 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 ces 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

x + y saturé.

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 relatif à 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 efficacement en charge l'arithmétique saturante sur les vecteurs SIMD, y compris SSE2 pour x86 et NEON pour ARM.

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

Implémentation possible

Voir libstdc++ (GCC), libc++ (Clang).

Exemple

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

Voir aussi

opération de soustraction saturante sur deux entiers
(modèle de fonction)
opération de multiplication saturante sur deux entiers
(modèle de fonction)
opération de division saturante sur deux entiers
(modèle de fonction)
renvoie une valeur entière limitée à la plage d'un autre type entier
(modèle de fonction)
(C++17)
limite une valeur entre deux valeurs limites
(modèle de fonction & objet fonction d'algorithme)
vérifie si une valeur entière est dans la plage d'un type entier donné
(modèle de fonction)
[statique]
renvoie la plus petite valeur finie du type non flottant donné, ou la plus petite valeur normale positive du type flottant donné
(fonction membre publique statique de std::numeric_limits<T>)
[statique]
renvoie la plus grande valeur finie du type donné
(fonction membre publique statique de std::numeric_limits<T>)

Liens externes

1.  Une implémentation sans branchement de l'arithmétique saturante — Locklessinc.com, 2012