Namespaces
Variants

ckd_mul

ja.cppreference.net より
ヘッダ <stdckdint.h>
#define ckd_mul( result, a, b ) /* implementation-defined */
// exposed interface:
bool ckd_mul( type1* result, type2 a, type3 b );
で定義 (C23 以降)

乗算 x × y を計算し、結果を *result に格納する。乗算は、両方のオペランドが無限範囲の符号付き整数型で表現され、その結果がこの整数型から type1 に変換されたかのように実行される。*result に代入された値が演算の数学的な結果を正しく表す場合、false を返す。そうでない場合、true を返す。この場合、*result に代入される値は、演算の数学的な結果を *result の幅にラップアラウンドしたものである。

引数

a, b - 整数値
result - 結果を格納するアドレス

戻り値

false *result に代入された値が乗算の数学的な結果を正しく表す場合は true を返し、そうでない場合は偽を返す。

注釈

type2 と type3 はどちらも、「プレーンな」char、bool、ビット精度整数型、または列挙型以外の任意の整数型でなければならず、同じ型でもよい。*result は、「プレーンな」char、bool、ビット精度整数型、または列挙型以外の任意の整数型の変更可能な左辺値でなければならない。

もし type2 または type3 が適切な整数型でない場合、または *result が適切な整数型の変更可能な左辺値でない場合は、診断メッセージを生成することが推奨される。

例

#include <limits.h>
#include <stdckdint.h>
#include <stdint.h>
#include <stdio.h>

const char* text(bool overflow) { return overflow ? "Overflow" : "OK"; }

int main()
{
    uint8_t x;
    uint16_t y;
    uint16_t result_uint16;
    uint32_t result_uint32;
    bool overflow;

    x = 2;
    y = 21;
    overflow = ckd_mul(&result_uint16, x, y);
    printf("%u * %u => %u (%s)\n", x, y, result_uint16, text(overflow));

    x = 2;
    y = UINT16_MAX;
    overflow = ckd_mul(&result_uint16, x, y);
    printf("%u * %u => %u (%s)\n", x, y, result_uint16, text(overflow));

    x = 2;
    y = UINT16_MAX;
    overflow = ckd_mul(&result_uint32, x, y);
    printf("%u * %u => %u (%s)\n", x, y, result_uint32, text(overflow));
}

出力:

2 * 21 => 42 (OK)
2 * 65535 => 65534 (Overflow)
2 * 65535 => 131070 (OK)

参考文献

  • C23 標準 (ISO/IEC 9899:2024):
  • 7.20.1 チェック付き整数演算マクロ ckd_ (p: 311)

関連項目

2つの整数のチェック付き加算演算
(型総称関数マクロ)
2つの整数のチェック付き減算演算
(型総称関数マクロ)