名前空間
変種
操作

fma, fmaf, fmal

From cppreference.com
< c‎ | numeric‎ | math
 
 
 
共通の数学関数
関数
基本的な数学関数
(C99)
fma
(C99)
(C99)
(C99)(C99)(C99)(C23)
最大/最小演算
(C99)
(C99)
指数関数
(C23)
(C99)
(C99)
(C23)
(C23)

(C99)
(C99)(C23)
(C23)
(C23)
べき乗関数
(C99)
(C23)
(C23)

(C99)
(C23)
(C23)
三角関数と双曲線関数
(C23)
(C23)
(C23)
(C23)
(C99)
(C99)
(C99)
最も近い整数浮動小数点数
(C99)(C99)(C99)
(C99)

(C99)(C99)(C99)
(C23)(C23)(C23)(C23)
浮動小数点操作
(C99)(C99)
(C99)(C23)
(C99)
縮小演算
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
量子および量子指数
Decimal再エンコーディング関数
総順序およびペイロード関数
分類
(C99)
(C99)
(C99)
(C23)
誤差関数とガンマ関数
(C99)
(C99)
(C99)
(C99)
マクロ定数
特殊な浮動小数点値
(C99)(C23)
引数と戻り値
エラーハンドリング
高速演算インジケータ
 
ヘッダー <math.h> で定義
float       fmaf( float x, float y, float z );
(1) (C99以降)
double      fma( double x, double y, double z );
(2) (C99以降)
long double fmal( long double x, long double y, long double z );
(3) (C99以降)
#define FP_FAST_FMA  /* 実装定義 */
(4) (C99以降)
#define FP_FAST_FMAF /* 実装定義 */
(5) (C99以降)
#define FP_FAST_FMAL /* 実装定義 */
(6) (C99以降)
ヘッダー <tgmath.h> で定義
#define fma( x, y, z )
(7) (C99以降)
1-3) (x * y) + z を無限精度で計算し、結果型に収まるように一度だけ丸めるとして計算します。
4-6) マクロ定数 FP_FAST_FMAFP_FAST_FMAF、または FP_FAST_FMAL が定義されている場合、対応する関数 fmafmaf、または fmal は、それぞれ doublefloat、および long double の引数に対して、式 x * y + z よりも高速(かつ高精度)に評価されます。定義されている場合、これらのマクロは整数 1 として評価されます。
7) 型汎用マクロ:いずれかの引数が long double 型の場合、fmal が呼び出されます。それ以外の場合、いずれかの引数が整数型または double 型の場合、fma が呼び出されます。それ以外の場合、fmaf が呼び出されます。

目次

[編集] パラメータ

x, y, z - 浮動小数点値

[編集] 戻り値

成功した場合、(x * y) + z の値を、無限精度で計算され、結果型に収まるように一度だけ丸められた値(または、単一の三項浮動小数点演算として計算された値)として返します。

オーバーフローによる範囲エラーが発生した場合、±HUGE_VAL±HUGE_VALF、または ±HUGE_VALL が返されます。

アンダーフローによる範囲エラーが発生した場合、(丸め後の)正しい値を返します。

[編集] エラー処理

エラーは math_errhandling で指定されたとおりに報告されます。

実装がIEEE浮動小数点算術 (IEC 60559) をサポートしている場合、

  • x がゼロで y が無限大であるか、または x が無限大で y がゼロである場合、そして
    • z が NaN でない場合、NaN が返され、FE_INVALID が発生します。
    • z が NaN である場合、NaN が返され、FE_INVALID が発生する可能性があります。
  • x * y が正確な無限大であり、z が逆符号の無限大である場合、NaN が返され、FE_INVALID が発生します。
  • x または y が NaN の場合、NaN が返されます。
  • z が NaN であり、x * y0 * Inf または Inf * 0 でない場合、NaN が返されます(FE_INVALID なし)。

[編集] 注意

この演算は、CPU の 融合積和演算 (fused multiply-add) 命令としてハードウェアで実装されることが一般的です。ハードウェアがサポートしている場合、適切な FP_FAST_FMA* マクロが定義されることが期待されますが、多くの実装では、マクロが定義されていない場合でも CPU 命令を利用します。

POSIX ではx * y の値が無効で z が NaN である状況は、ドメインエラーとして指定されています。

無限の中間精度のため、fma は、sqrt や、CPU で提供されていない場合の除算(例:Itanium)など、他の正しく丸められた数学演算の一般的な構成要素となります。

すべての浮動小数点式と同様に、式 (x * y) + z は、 #pragma STDC FP_CONTRACT がオフでない限り、融合積和演算としてコンパイルされる可能性があります。

[編集]

#include <fenv.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
// #pragma STDC FENV_ACCESS ON
 
int main(void)
{
    // demo the difference between fma and built-in operators
    double in = 0.1;
    printf("0.1 double is %.23f (%a)\n", in, in);
    printf("0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3),"
           " or 1.0 if rounded to double\n");
    double expr_result = 0.1 * 10 - 1;
    printf("0.1 * 10 - 1 = %g : 1 subtracted after "
           "intermediate rounding to 1.0\n", expr_result);
    double fma_result = fma(0.1, 10, -1);
    printf("fma(0.1, 10, -1) = %g (%a)\n", fma_result, fma_result);
 
    // fma use in double-double arithmetic
    printf("\nin double-double arithmetic, 0.1 * 10 is representable as ");
    double high = 0.1 * 10;
    double low = fma(0.1, 10, -high);
    printf("%g + %g\n\n", high, low);
 
    // error handling
    feclearexcept(FE_ALL_EXCEPT);
    printf("fma(+Inf, 10, -Inf) = %f\n", fma(INFINITY, 10, -INFINITY));
    if (fetestexcept(FE_INVALID))
        puts("    FE_INVALID raised");
}

実行結果の例

0.1 double is 0.10000000000000000555112 (0x1.999999999999ap-4)
0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), or 1.0 if rounded to double
0.1 * 10 - 1 = 0 : 1 subtracted after intermediate rounding to 1.0
fma(0.1, 10, -1) = 5.55112e-17 (0x1p-54)
 
in double-double arithmetic, 0.1 * 10 is representable as 1 + 5.55112e-17
 
fma(+Inf, 10, -Inf) = -nan
    FE_INVALID raised

[編集] 参照

  • C23標準 (ISO/IEC 9899:2024)
  • 7.12.13.1 The fma functions (p: TBD)
  • 7.25 Type-generic math <tgmath.h> (p: TBD)
  • F.10.10.1 The fma functions (p: TBD)
  • C17標準 (ISO/IEC 9899:2018)
  • 7.12.13.1 The fma functions (p: 188-189)
  • 7.25 型総称数学関数 <tgmath.h> (p: 272-273)
  • F.10.10.1 The fma functions (p: 386)
  • C11標準 (ISO/IEC 9899:2011)
  • 7.12.13.1 The fma functions (p: 258)
  • 7.25 型総称数学関数 <tgmath.h> (p: 373-375)
  • F.10.10.1 The fma functions (p: 530)
  • C99標準 (ISO/IEC 9899:1999)
  • 7.12.13.1 The fma functions (p: 239)
  • 7.22 型総称数学関数 <tgmath.h> (p: 335-337)
  • F.9.10.1 The fma functions (p: 466)

[編集] 関連項目

浮動小数点除算演算の符号付き余りを計算する
(関数) [編集]
(C99)(C99)(C99)
符号付き余りおよび除算演算の最後の3ビットを計算する
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)