◆ fms()

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

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

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

But really conformant fused multiply/substract also implies

  • only one rounding
  • no "intermediate" overflow

fms 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 fms capabilities in all circumstances in your own code you can use the pedantic_ decorator (can be very expensive).

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