首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

std::fma

Defined in header <cmath>

?

?

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

(1)

(since C++11)

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)

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%29次计算(x*y) + z好像要达到无限的精度,并且只舍入一次,以适应结果类型。

的所有参数组合的一组重载或函数模板算术类型不包括在1-3%29。如果有任何争论积分型,它被铸造成double.如果任何其他论点是long double,则返回类型为long double,否则就是double...

5-7%29如果宏常量FP_FAST_FMAF,,,FP_FAST_FMA,或FP_FAST_FMAL定义的函数std::fma除了比表达式更精确的%29之外,计算速度更快的%28x*y+zfloat,,,double,和long double分别争论。如果定义了这些宏,则这些宏将计算为整数。1...

参数

x, y, z

-

values of floating-point or integral types

返回值

如果成功,则返回(x*y) + z似乎计算到无限精度,并舍入一次以适应结果类型%28,或者,或者,计算为单个三元浮点操作%29。

如果溢出导致范围错误,±HUGE_VAL,,,±HUGE_VALF,或±HUGE_VALL会被归还。

如果由于下流发生范围错误,则返回舍入%29后的正确值%28。

错误处理

错误按数学[医]错误处理...

如果实现支持ieee浮点算法%28IEC 60559%29,

  • 如果x是零,y是无限的,或者x是无穷的,y是零,而z不是NaN,则NaN返回FE_INVALID提出来
  • 如果x是零,y是无穷的,或者x是无穷的,y是零,z是NaN,则NaN返回FE_INVALID可能被提高
  • 如果x%2Ay是一个精确的无穷大,z是带相反符号的无穷大,NaN返回,FE_INVALID提出来
  • 如果x或y为nan,则返回nan。
  • 如果z是nan,则x%2Ay=%27T0%2Ainf或inf%2A0,则NaN返回%28而不使用FE。[医]无效%29

注记

此操作通常在硬件中实现,如融合相加CPU指令。如果硬件支持,则适当的FP_FAST_FMA*宏是需要定义的,但是即使没有定义宏,许多实现也会使用CPU指令。

POSIX额外指定指定返回的情况FE_INVALID是域错误。

由于其无限的中间精度,fma是其他正确四舍五入的数学操作的一个常见的构建块,例如std::sqrt甚至分割%28,在CPU不提供的地方,例如Itanium%29。

与所有浮点表达式一样,表达式(x*y) + z可以编译为一个融合的乘法添加,除非#语用STDC FP_CONTRACT已经关机了。

二次

代码语言:javascript
复制
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cfenv>
#pragma STDC FENV_ACCESS ON
int main()
{
    // demo the difference between fma and built-in operators
    double 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";
    double expr_result = 0.1 * 10 - 1;
    double fma_result = 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 arithmetic
    double high = 0.1 * 10;
    double low = fma(0.1, 10, -high);
    std::cout << "in double-double arithmetic, 0.1 * 10 is representable as "
              << high << " + " << low << "\n\n";
 
    // error handling 
    std::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";
}

二次

可能的产出:

二次

代码语言:javascript
复制
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
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

二次

另见

remainder (C++11)

signed remainder of the division operation (function)

remquo (C++11)

signed remainder as well as the three last bits of the division operation (function)

c FMA文件

代码语言:txt
复制
 ? cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com