Namespaces
Variants

std:: add_sat

From cppreference.net
Saturation arithmetic
Functions
add_sat
(C++26)
(C++26)
(C++26)
(C++26)
ヘッダーで定義 <numeric>
template < class T >
constexpr T add_sat ( T x, T y ) noexcept ;
(C++26以降)

飽和 加算 x + y を計算します。この演算は(組み込みの 整数演算 とは異なり) 無限 の範囲を持つ数学的演算であるかのように振る舞います。このような演算の結果を 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 .

注記

組み込みの整数演算子とは異なり、 integral promotion x および y 引数には適用されません。

異なる型の2つの引数が渡された場合、その呼び出しはコンパイルに失敗します。つまり、 テンプレート引数推論 に関する動作は、 std::min std::max と同じです。

最新のハードウェアアーキテクチャの多くは、 SIMDベクトル に対する飽和演算を効率的にサポートしています。これには SSE2 x86 向け)や NEON ARM 向け)が含まれます。

機能テスト マクロ 標準 機能
__cpp_lib_saturation_arithmetic 202311L (C++26) 飽和算術演算

実装例

以下を参照してください libstdc++ (gcc)

Compiler Explorer でプレビューできます。

#include <climits>
#include <limits>
#include <numeric>
static_assert(CHAR_BIT == 8);
static_assert(UCHAR_MAX == 255);
int main()
{
    constexpr int a = std::add_sat(3, 4); // 飽和は発生せず、T = int
    static_assert(a == 7);
    constexpr unsigned char b = std::add_sat<unsigned char>(UCHAR_MAX, 4); // 飽和発生
    static_assert(b == UCHAR_MAX);
    constexpr unsigned char c = std::add_sat(UCHAR_MAX, 4); // 飽和せず、T = int
        // add_sat(int, int) は int tmp == 259 を返し、
        // 代入時に 259 % 256 == 3 に切り詰められる
    static_assert(c == 3);
//  unsigned char d = std::add_sat(252, c); // エラー: T の推論が矛盾
    constexpr unsigned char e = std::add_sat<unsigned char>(251, a); // 飽和発生
    static_assert(e == UCHAR_MAX);
        // 251 は型 T = unsigned char、`a` は unsigned char 値に変換される;
        // `a` に対して int -> unsigned char 変換警告が発生する可能性あり
    constexpr signed char f = std::add_sat<signed char>(-123, -3); // 飽和せず
    static_assert(f == -126);
    constexpr signed char g = std::add_sat<signed char>(-123, -13); // 飽和発生
    static_assert(g == std::numeric_limits<signed char>::min()); // g == -128
}

関連項目

(C++26)
2つの整数に対する飽和減算演算
(関数テンプレート)
(C++26)
2つの整数に対する飽和乗算演算
(関数テンプレート)
(C++26)
2つの整数に対する飽和除算演算
(関数テンプレート)
別の整数型の範囲にクランプされた整数値を返す
(関数テンプレート)
(C++17)
値を境界値のペアの間でクランプする
(関数テンプレート)
(C++20)
整数値が指定された整数型の範囲内にあるかどうかをチェックする
(関数テンプレート)
[static]
指定された非浮動小数点型の最小有限値、または指定された浮動小数点型の最小正の正規値を返す
( std::numeric_limits<T> のpublic staticメンバ関数)
[static]
指定された型の最大有限値を返す
( std::numeric_limits<T> のpublic staticメンバ関数)

外部リンク

1. 飽和演算の分岐なし実装 — Locklessinc.com, 2012
2. C++ Weekly - Ep 459 - C++26の飽和数学演算 — Youtube.com, 2024-12-16