std::saturating_add
ja.cppreference.net より
| ヘッダで定義 <numeric>
|
||
template< class T >
constexpr T saturating_add( T x, T y ) noexcept;
|
(C++26 以降) | |
飽和加算を計算しますx + y。この演算は(組み込みの 整数に対する算術演算)とは異なり、無限範囲の数学的演算であるかのように振る舞います。q をqそのような演算の結果とします。
戻り値:
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.
ノート
組み込みの整数算術演算子とは異なり、整数昇格は x および y 引数には適用されません。
異なる型の2つの引数が渡された場合、呼び出しはコンパイルに失敗します。つまり、テンプレート実引数推定に関する動作は、std::min や std::max と同じです。
最近のほとんどのハードウェアアーキテクチャは、SIMD ベクトル上での飽和演算を効率的にサポートしており、SSE2(x86向け)や NEON(ARM向け)などがあります。
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_saturation_arithmetic |
202311L |
(C++26) | 飽和演算 |
202603L |
(C++26) | 飽和演算関数の改名 |
実装例
参照: libstdc++ (GCC), libc++ (Clang).
例
次の場所でプレビューできます: 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
}
関連項目
(C++26) |
2つの整数に対する飽和減算演算 (関数テンプレート) |
(C++26) |
2つの整数に対する飽和乗算演算 (関数テンプレート) |
(C++26) |
2つの整数に対する飽和除算演算 (関数テンプレート) |
(C++26) |
整数値を別の整数型の範囲にクランプして返す (関数テンプレート) |
(C++17) |
値を一対の境界値の間にクランプする (関数テンプレート & アルゴリズム関数オブジェクト) |
(C++20) |
|
(C++20) |
整数値が指定された整数型の範囲内にあるかどうかを調べる (関数テンプレート) |
[static] |
指定された非浮動小数点型の最小有限値、または指定された浮動小数点型の最小正の正規化された値を返す ( std::numeric_limits<T> のパブリック静的メンバ関数)
|
[static] |
指定された型の最大有限値を返す ( std::numeric_limits<T> のパブリック静的メンバ関数)
|
外部リンク
| 1. | 飽和演算の分岐なし実装 — Locklessinc.com, 2012 |