◆ fnma()

Value boost::simd::fnma ( Value const &  x,
Value const &  y,
Value const &  z 
)

This function object computes the negated (fused) multiply add of its three parameters.

Header <boost/simd/function/fnma.hpp>
Notes
The call fnma(x, y, z) is similar to -x*y-z

But really conformant fused multiply/add also implies

  • only one rounding
  • no "intermediate" overflow

fnma provides this for all integral types (however, using it on unsigned types is not recommanded for obvious reasons) and also each time it is reasonable in terms of performance for floating ones (i.e. if the system has the hard wired capability).

If you need pedantic fnma capabilities in all circumstances in your own code you can use the pedantic_ decorator (can be very expensive).

Decorators
  • pedantic_ ensures the fnma properties and allows SIMD acceleration if available.
See also
fms, fma, fnms
Example:
#include <boost/simd/arithmetic.hpp>
#include <boost/simd/pack.hpp>
#include <boost/simd/function/enumerate.hpp>
#include <iostream>
namespace bs = boost::simd;
using pack_ft = bs::pack <float, 4>;
int main()
{
pack_ft pf = bs::enumerate<pack_ft>(-1, 2);
pack_ft qf = bs::enumerate<pack_ft>( 0, 3);
pack_ft rf = bs::enumerate<pack_ft>( 2, 5);
std::cout
<< "---- simd" << '\n'
<< " <- pf = " << pf << '\n'
<< " <- qf = " << qf << '\n'
<< " <- rf = " << rf << '\n'
<< " -> bs::fnma(pf, qf, rf) = " << bs::fnma(pf, qf, rf) << '\n';
float xf = 3.0f, yf = -3.0f, zf = 2.0f;
std::cout
<< "---- scalar" << '\n'
<< " <- xf = " << xf << '\n'
<< " <- yf = " << yf << '\n'
<< " <- yf = " << zf << '\n'
<< " -> bs::fnma(xf, yf, rf) = " << bs::fnma(xf, yf, zf) << '\n';
return 0;
}
Possible output:
---- simd
<- pf = (-1, 1, 3, 5)
<- qf = (0, 3, 6, 9)
<- rf = (2, 7, 12, 17)
-> bs::fnma(pf, qf, rf) = (-2, -10, -30, -62)
---- scalar
<- xf = 3
<- yf = -3
<- yf = 2
-> bs::fnma(xf, yf, rf) = 7