Namespaces
Variants

std::saturating_mul

ja.cppreference.net より
 
 
 
 
ヘッダ <numeric>
template< class T >
constexpr T saturating_mul( 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_mul<int>(2, 3) == 6) // not saturated
    && (std::saturating_mul<int>(INT_MAX / 2, 3) == INT_MAX) // saturated
    && (std::saturating_mul<int>(-2, 3) == -6) // not saturated
    && (std::saturating_mul<int>(INT_MIN / -2, -3) == INT_MIN) // saturated
    && (std::saturating_mul<unsigned>(2, 3) == 6) // not saturated
    && (std::saturating_mul<unsigned>(UINT_MAX / 2, 3) == UINT_MAX) // saturated
);

int main() {}

関連項目

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

外部リンク

1.  飽和演算の分岐なし実装 — Locklessinc.com, 2012