std::fma,std::fmaf,std::fmal (3) - Linux Man Pages
Defined in header <cmath>
float fma ( float x, float y, float z ); (1) (since C++11)
float fmaf( float x, float y, float z );
double fma ( double x, double y, double z ); (2) (since C++11)
long double fma ( long double x, long double y, long double z ); (3) (since C++11)
long double fmal( long double x, long double y, long double z );
Promoted fma ( Arithmetic1 x, Arithmetic2 y, Arithmetic3 z ); (4) (since C++11)
#define FP_FAST_FMA /* implementation-defined */ (5) (since C++11)
#define FP_FAST_FMAF /* implementation-defined */ (6) (since C++11)
#define FP_FAST_FMAL /* implementation-defined */ (7) (since C++11)
1-3) Computes (x*y) + z as if to infinite precision and rounded only once to fit the result type.
4) A set of overloads or a function template for all combinations of arguments of arithmetic_type not covered by 1-3). If any argument has integral_type, it is cast to double. If any other argument is long double, then the return type is long double, otherwise it is double.
5-7) If the macro constants FP_FAST_FMAF, FP_FAST_FMA, or FP_FAST_FMAL are defined, the function std::fma evaluates faster (in addition to being more precise) than the expression x*y+z for float, double, and long double arguments, respectively. If defined, these macros evaluate to integer 1.
x, y, z - values of floating-point or integral_types
If successful, returns the value of (x*y) + z as if calculated to infinite precision and rounded once to fit the result type (or, alternatively, calculated as a single ternary floating-point operation)
If a range error due to overflow occurs, ±HUGE_VAL, ±HUGE_VALF, or ±HUGE_VALL is returned.
If a range error due to underflow occurs, the correct value (after rounding) is returned.
Errors are reported as specified in math_errhandling.
If the implementation supports IEEE floating-point arithmetic (IEC 60559),
* If x is zero and y is infinite or if x is infinite and y is zero, and z is not a NaN, then NaN is returned and FE_INVALID is raised
* If x is zero and y is infinite or if x is infinite and y is zero, and z is a NaN, then NaN is returned and FE_INVALID may be raised
* If x*y is an exact infinity and z is an infinity with the opposite sign, NaN is returned and FE_INVALID is raised
* If x or y are NaN, NaN is returned
* If z is NaN, and x*y aren't 0*Inf or Inf*0, then NaN is returned (without FE_INVALID)
This operation is commonly implemented in hardware as fused_multiply-add CPU instruction. If supported by hardware, the appropriate FP_FAST_FMA* macros are expected to be defined, but many implementations make use of the CPU instruction even when the macros are not defined.
POSIX_additionally_specifies that the situations specified to return FE_INVALID are domain errors.
Due to its infinite intermediate precision, fma is a common building block of other correctly-rounded mathematical operations, such as std::sqrt or even the division (where not provided by the CPU, e.g. Itanium)
As with all floating-point expressions, the expression (x*y) + z may be compiled as a fused multiply-add unless the #pragma STDC FP_CONTRACT is off.
// Run this code
remainderl signed remainder of the division operation
remquol signed remainder as well as the three last bits of the division operation