Namespaces
Variants

std::saturating_sub

ja.cppreference.net より
 
 
 
 
ヘッダ <numeric>
template< class T >
constexpr T saturating_sub( T x, T y ) noexcept;
で定義 (C++26 以上)

飽和減算 x - y を計算します。この演算は、(組み込みの 整数に対する算術演算 とは異なり) あたかも 無限 範囲を持つ数学的な演算であるかのように動作します。そのような演算の結果を 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 <numeric>
 
static_assert
(""
    && (std::saturating_sub<int>(INT_MIN + 4, 3) == INT_MIN + 1) // not saturated
    && (std::saturating_sub<int>(INT_MIN + 4, 5) == INT_MIN) // saturated
    && (std::saturating_sub<int>(INT_MAX - 4, -3) == INT_MAX - 1) // not saturated
    && (std::saturating_sub<int>(INT_MAX - 4, -5) == INT_MAX) // saturated
    && (std::saturating_sub<unsigned>(4, 3) == 1) // not saturated
    && (std::saturating_sub<unsigned>(4, 5) == 0) // saturated
);

int main() {}

関連項目

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

外部リンク

1.  飽和演算のブランチフリー実装 — Locklessinc.com, 2012