fma, fmaf, fmal
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
定義済みヘッダー
<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 /* implementation-defined */
|
(4) | (C99以降) |
|
#define FP_FAST_FMAF /* implementation-defined */
|
(5) | (C99以降) |
|
#define FP_FAST_FMAL /* implementation-defined */
|
(6) | (C99以降) |
|
定義済みヘッダー
<tgmath.h>
|
||
|
#define fma( x, y, z )
|
(7) | (C99以降) |
FP_FAST_FMA
、
FP_FAST_FMAF
または
FP_FAST_FMAL
が定義されている場合、対応する関数
fma
、
fmaf
または
fmal
は、それぞれ
x
*
y
+
z
という式よりも(より正確であることに加えて)高速に評価されます。定義されている場合、これらのマクロは整数
1
に評価されます。
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 * y が 0 * Inf または Inf * 0 でない場合、NaNが返される( FE_INVALID なし)
注記
この演算は一般的にハードウェアで fused multiply-add CPU命令として実装されています。ハードウェアでサポートされている場合、適切な 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) { // fmaと組み込み演算子の違いをデモンストレーション 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); // double-double演算におけるfmaの使用 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); // エラー処理 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 fma関数群 (p: TBD)
-
- 7.25 総称数学 <tgmath.h> (p: TBD)
-
- F.10.10.1 fma関数群 (p: TBD)
- C17規格 (ISO/IEC 9899:2018):
-
- 7.12.13.1 fma関数群 (p: 188-189)
-
- 7.25 総称数学 <tgmath.h> (p: 272-273)
-
- F.10.10.1 fma関数群 (p: 386)
- C11規格 (ISO/IEC 9899:2011):
-
- 7.12.13.1 fma関数群 (p: 258)
-
- 7.25 総称型数学 <tgmath.h> (p: 373-375)
-
- F.10.10.1 fma関数群 (p: 530)
- C99規格 (ISO/IEC 9899:1999):
-
- 7.12.13.1 fma関数群 (p: 239)
-
- 7.22 総称型数学 <tgmath.h> (p: 335-337)
-
- F.9.10.1 fma関数群 (p: 466)
関連項目
|
(C99)
(C99)
(C99)
|
浮動小数点除算操作の符号付き剰余を計算する
(関数) |
|
(C99)
(C99)
(C99)
|
符号付き剰余と除算操作の下位3ビットを計算する
(関数) |
|
C++ documentation
for
fma
|
|