diff --git a/src/core/include/mp-units/math.h b/src/core/include/mp-units/math.h index e6957201..c93883c6 100644 --- a/src/core/include/mp-units/math.h +++ b/src/core/include/mp-units/math.h @@ -237,6 +237,29 @@ template common_reference(R * S, T)}; } +/** + * @brief Computes the fma of 2 quantities and a quantity point + * + * @param a: Multiplicand + * @param x: Multiplicand + * @param b: Addend + * @return QuantityPoint: The nearest floating point representable to ax+b + */ +template + requires requires { common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } && + (get_unit(R) * get_unit(S) == get_unit(T)) && requires(Rep1 v1, Rep2 v2, Rep3 v3) { + requires requires { fma(v1, v2, v3); } || requires { std::fma(v1, v2, v3); }; + } +[[nodiscard]] constexpr QuantityPointOf< + common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), + get_quantity_spec(T))> auto fma(const quantity& a, const quantity& x, + const quantity_point& b) noexcept +{ + using std::fma; + return Origin + quantity{fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), + b.quantity_ref_from(b.point_origin).numerical_value_ref_in(b.unit)), + common_reference(R * S, T)}; +} /** * @brief Computes the floating-point remainder of the division operation x / y.