Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::fma,std::fmaf,std::fmal

      From cppreference.com
      <cpp‎ |numeric‎ |math
       
       
       
      Common mathematical functions
      Nearest integer floating point operations
      (C++11)(C++11)(C++11)
      (C++11)
      (C++11)
      (C++11)(C++11)(C++11)
      Floating point manipulation functions
      (C++11)(C++11)
      (C++11)
      (C++11)
      Classification and comparison
      (C++11)
      (C++11)
      (C++11)
      (C++11)
      (C++11)
      (C++11)
      Types
      (C++11)
      (C++11)
      (C++11)
      Macro constants
       
      Defined in header<cmath>
      (1)
      float       fma(float x,float y,float z);

      double      fma(double x,double y,double z);

      longdouble fma(longdouble x,longdouble y,longdouble z);
      (since C++11)
      (until C++23)
      constexpr/* floating-point-type */

                  fma(/* floating-point-type */ x,
                       /* floating-point-type */ y,

                       /* floating-point-type */ z);
      (since C++23)
      float       fmaf(float x,float y,float z);
      (2)(since C++11)
      (constexpr since C++23)
      longdouble fmal(longdouble x,longdouble y,longdouble z);
      (3)(since C++11)
      (constexpr since C++23)
      #define FP_FAST_FMA  /* implementation-defined */
      (4)(since C++11)
      #define FP_FAST_FMAF /* implementation-defined */
      (5)(since C++11)
      #define FP_FAST_FMAL /* implementation-defined */
      (6)(since C++11)
      Defined in header<cmath>
      template<class Arithmetic1,class Arithmetic2,class Arithmetic3>

      /* common-floating-point-type */

          fma( Arithmetic1 x, Arithmetic2 y, Arithmetic3 z);
      (A)(since C++11)
      (constexpr since C++23)
      1-3) Computesx* y+ z as if to infinite precision and rounded only once to fit the result type. The library provides overloads ofstd::fma for all cv-unqualified floating-point types as the type of the parametersx,y andz.(since C++23)
      4-6) If the macro constantsFP_FAST_FMA,FP_FAST_FMAF, orFP_FAST_FMAL are defined, the functionstd::fma evaluates faster (in addition to being more precise) than the expressionx* y+ z fordouble,float, andlongdouble arguments, respectively. If defined, these macros evaluate to integer1.
      A) Additional overloads are provided for all other combinations of arithmetic types.

      Contents

      [edit]Parameters

      x, y, z - floating-point or integer values

      [edit]Return value

      If successful, returns the value ofx* 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.

      [edit]Error handling

      Errors are reported as specified inmath_errhandling.

      If the implementation supports IEEE floating-point arithmetic (IEC 60559),

      • Ifx is zero andy is infinite or ifx is infinite andy is zero, and
        • ifz is not a NaN, then NaN is returned andFE_INVALID is raised,
        • ifz is a NaN, then NaN is returned andFE_INVALID may be raised.
      • Ifx* y is an exact infinity andz is an infinity with the opposite sign, NaN is returned andFE_INVALID is raised.
      • Ifx ory are NaN, NaN is returned.
      • Ifz is NaN, andx* y is not0* Inf orInf*0, then NaN is returned (withoutFE_INVALID).

      [edit]Notes

      This operation is commonly implemented in hardware asfused multiply-add CPU instruction. If supported by hardware, the appropriateFP_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(fma,fmaf,fmal) additionally specifies that the situations specified to returnFE_INVALID are domain errors.

      Due to its infinite intermediate precision,std::fma is a common building block of other correctly-rounded mathematical operations, such asstd::sqrt or even the division (where not provided by the CPU, e.g.Itanium).

      As with all floating-point expressions, the expressionx* y+ z may be compiled as a fused multiply-add unless the#pragmaSTDC FP_CONTRACT is off.

      The additional overloads are not required to be provided exactly as(A). They only need to be sufficient to ensure that for their first argumentnum1, second argumentnum2 and third argumentnum3:

      • Ifnum1,num2 ornum3 has typelongdouble, thenstd::fma(num1, num2, num3) has the same effect asstd::fma(static_cast<longdouble>(num1),
                 static_cast<longdouble>(num2),
                 static_cast<longdouble>(num3))
        .
      • Otherwise, ifnum1,num2 and/ornum3 has typedouble or an integer type, thenstd::fma(num1, num2, num3) has the same effect asstd::fma(static_cast<double>(num1),
                 static_cast<double>(num2),
                 static_cast<double>(num3))
        .
      • Otherwise, ifnum1,num2 ornum3 has typefloat, thenstd::fma(num1, num2, num3) has the same effect asstd::fma(static_cast<float>(num1),
                 static_cast<float>(num2),
                 static_cast<float>(num3))
        .
      (until C++23)

      Ifnum1,num2 andnum3 have arithmetic types, thenstd::fma(num1, num2, num3) has the same effect asstd::fma(static_cast</*common-floating-point-type*/>(num1),
               static_cast</*common-floating-point-type*/>(num2),
               static_cast</*common-floating-point-type*/>(num3))
      , where/*common-floating-point-type*/ is the floating-point type with the greatestfloating-point conversion rank and greatestfloating-point conversion subrank among the types ofnum1,num2 andnum3, arguments of integer type are considered to have the same floating-point conversion rank asdouble.

      If no such floating-point type with the greatest rank and subrank exists, thenoverload resolution does not result in a usable candidate from the overloads provided.

      (since C++23)

      [edit]Example

      Run this code
      #include <cfenv>#include <cmath>#include <iomanip>#include <iostream> #ifndef __GNUC__#pragma STDC FENV_ACCESS ON#endif int main(){// demo the difference between fma and built-in operatorsconstdouble in=0.1;std::cout<<"0.1 double is "<<std::setprecision(23)<< in<<" ("<<std::hexfloat<< in<<std::defaultfloat<<")\n"<<"0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), "<<"or 1.0 if rounded to double\n"; constdouble expr_result=0.1*10-1;constdouble fma_result= std::fma(0.1,10,-1);std::cout<<"0.1 * 10 - 1 = "<< expr_result<<" : 1 subtracted after intermediate rounding\n"<<"fma(0.1, 10, -1) = "<<std::setprecision(6)<< fma_result<<" ("<<std::hexfloat<< fma_result<<std::defaultfloat<<")\n\n"; // fma is used in double-double arithmeticconstdouble high=0.1*10;constdouble low= std::fma(0.1,10,-high);std::cout<<"in double-double arithmetic, 0.1 * 10 is representable as "<< high<<" + "<< low<<"\n\n"; // error handlingstd::feclearexcept(FE_ALL_EXCEPT);std::cout<<"fma(+Inf, 10, -Inf) = "<< std::fma(INFINITY,10,-INFINITY)<<'\n';if(std::fetestexcept(FE_INVALID))std::cout<<"    FE_INVALID raised\n";}

      Possible output:

      0.1 double is 0.10000000000000000555112 (0x1.999999999999ap-4)0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), or 1.0 if rounded to double0.1 * 10 - 1 = 0 : 1 subtracted after intermediate roundingfma(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

      [edit]See also

      (C++11)(C++11)(C++11)
      signed remainder of the division operation
      (function)[edit]
      (C++11)(C++11)(C++11)
      signed remainder as well as the three last bits of the division operation
      (function)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/math/fma&oldid=181913"

      [8]ページ先頭

      ©2009-2025 Movatter.jp