◆ fnms()

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

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

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

But really conformant fused multiply/add also implies

  • only one rounding
  • no "intermediate" overflow

fnms provides this for all integral types 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 fnms capabilities in all circumstances in your own code you can use the pedantic_ decorator (can be very expensive).

Decorators
  • pedantic_ ensures the fnms properties and allows SIMD acceleration if available.
See also
fms, fma, fnma
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::fnms(pf, qf, rf) = " << bs::fnms(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::fnms(xf, yf, rf) = " << bs::fnms(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::fnms(pf, qf, rf) = (2, 4, -6, -28)
---- scalar
<- xf = 3
<- yf = -3
<- yf = 2
-> bs::fnms(xf, yf, rf) = 11