E.V.E
v2023.02.15

◆ fam

eve::fam = {}
inlineconstexpr

Computes the fused add multiply of its three parameters.

The call fam(x, y, z) is similar to x+y*z as if calculated to infinite precision and rounded once to fit the result as much as supported by the hardware.

Defined in Header

#include <eve/module/core.hpp>

Callable Signatures

namespace eve
{
template< eve::value T >
eve::common_value_t fam(T x, U y, V z) noexcept;
}
constexpr callable_fam_ fam
Computes the fused add multiply of its three parameters.
Definition: fam.hpp:81
Definition: abi.hpp:18
typename eve::detail::common_value_impl< void, Ts... >::type common_value_t
Computes the SIMD-compatible common type between all Ts.
Definition: common_value.hpp:50

Parameters

Return value

The value of x+y*z as if calculated to infinite precision and rounded once is returned, but only if the hardware is in capacity to do it at reasonable cost.

Note
This fam implementation provides those properties for all integral real value and when possible for floating real value.

Example

#include <eve/module/core.hpp>
#include <eve/wide.hpp>
#include <iostream>
#include <iomanip>
int main()
{
float es = eve::eps(eve::as<float>());
float esm1 = es-1.0f;
float esp1 = es+1.0f;
float vm = eve::valmax(eve::as<float>());
wide_t qf = {2, -3, esp1, vm};
wide_t pf = {3, -2, esm1, 2 };
wide_t of = {4, -1, 1.0f, -vm};
std::cout << "---- simd" << '\n'
<< " <- of = " << of << '\n'
<< " <- pf = " << pf << '\n'
<< " <- qf = " << qf << '\n'
<< " -> pedantic(fam)(of, pf, qf) = " << eve::pedantic(eve::fam)(of, pf, qf) << '\n'
<< " -> numeric(fam)(of, pf, qf) = " << eve::numeric(eve::fam)(of, pf, qf) << '\n'
<< " -> fam(of, pf, qf) = " << eve::fam(of, pf, qf) << '\n'
<< "\n if the last fam result ends by '0, inf}', it is because\n"
<< " the system has no simd fam family intrinsics\n"
<< " or is not configured to use them.\n\n";
std::cout << "---- scalar" << std::setprecision(10) << '\n'
<< " <- vm = " << vm << '\n'
<< " -> pedantic(fam)(vm, 2.0f, -vm) = " << eve::pedantic(eve::fam)(vm, 2.0f, -vm) << '\n'
<< " -> numeric(fam)(vm, 2.0f, -vm) = " << eve::numeric(eve::fam)(vm, 2.0f, -vm) << '\n'
<< " -> fam(vm, 2.0f, -vm) = " << eve::fam(vm, 2.0f, -vm) << '\n'
<< " <- esm1 = " << esm1 << '\n'
<< " <- esp1 = " << esp1 << '\n'
<< " -> pedantic(fam)(1.0f, esp1, esm1) = " << eve::pedantic(eve::fam)(1.0f, esp1, esm1) << '\n'
<< " -> numeric(fam)(1.0f, esp1, esm1) = " << eve::numeric(eve::fam)(1.0f, esp1, esm1) << '\n'
<< " -> fam(-1.0f, esp1, esm1) = " << eve::fam(-1.0f, esp1, esm1) << '\n';
return 0;
}
constexpr callable_valmax_ valmax
Computes the the greatest representable value.
Definition: valmax.hpp:55
constexpr callable_eps_ eps
Computes the the machine epsilon.
Definition: eps.hpp:63
constexpr pedantic_type const pedantic
Higher-order Callable Object imbuing more standard semantic onto other Callable Objects.
Definition: pedantic.hpp:56
constexpr numeric_type const numeric
Higher-order Callable Object imbuing non invalid return preference semantic onto other Callable Objec...
Definition: numeric.hpp:53
Lightweight type-wrapper.
Definition: as.hpp:29
Wrapper for SIMD registers.
Definition: wide.hpp:65

Semantic Modifiers

  • Masked Call

    The call eve::fam[mask](x, ...) provides a masked version of fam which is equivalent to if_else(mask, fam(x, ...), x)

    Example

    #include <eve/module/core.hpp>
    #include <eve/wide.hpp>
    #include <iostream>
    #include <iomanip>
    int main()
    {
    float es = eve::eps(eve::as<float>());
    float esm1 = es-1.0f;
    float esp1 = es+1.0f;
    float vm = eve::valmax(eve::as<float>());
    wide_t qf = {2, -3, esp1, vm};
    wide_t pf = {3, -2, esm1, 2 };
    wide_t of = {4, -1, 1.0f, -vm};
    std::cout << "---- simd" << '\n'
    << " <- of = " << of << '\n'
    << " <- pf = " << pf << '\n'
    << " <- qf = " << qf << '\n'
    << " -> fam[pf+of > 0](of, pf, qf) = " << eve::fam[pf+of > 0](of, pf, qf) << '\n';
    return 0;
    }
  • eve::pedantic, eve::numeric
    • The call pedantic(fam)(x,y,z) ensures the one rounding property. This can be very expensive if the system has no hardware capability.
    • The call numeric(fam)(x,y,z) ensures the full compliance to fam properties. This can be very expensive if the system has no hardware capability.
    • see the above regular example.