diff --git a/include/boost/decimal/detail/cmath/fma.hpp b/include/boost/decimal/detail/cmath/fma.hpp index 7efffc4c1..4c04b4e7e 100644 --- a/include/boost/decimal/detail/cmath/fma.hpp +++ b/include/boost/decimal/detail/cmath/fma.hpp @@ -14,299 +14,6 @@ namespace boost { namespace decimal { -/* -constexpr auto fmad32(decimal32 x, decimal32 y, decimal32 z) noexcept -> decimal32 -{ - // First calculate x * y without rounding - constexpr decimal32 zero {0, 0}; - - const auto res {detail::check_non_finite(x, y)}; - if (res != zero) - { - return res; - } - - auto sig_lhs {x.full_significand()}; - auto exp_lhs {x.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {y.full_significand()}; - auto exp_rhs {y.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - auto mul_result {detail::mul_impl(sig_lhs, exp_lhs, x.isneg(), sig_rhs, exp_rhs, y.isneg())}; - const decimal32 dec_result {mul_result.sig, mul_result.exp, mul_result.sign}; - - const auto res_add {detail::check_non_finite(dec_result, z)}; - if (res_add != zero) - { - return res_add; - } - - bool lhs_bigger {dec_result > z}; - if (dec_result.isneg() && z.isneg()) - { - lhs_bigger = !lhs_bigger; - } - bool abs_lhs_bigger {abs(dec_result) > abs(z)}; - - // To avoid the rounding step we promote the constituent pieces to the next higher type - detail::decimal64_components promoted_mul_result {static_cast(mul_result.sig), - mul_result.exp, mul_result.sign}; - - detail::normalize(promoted_mul_result.sig, promoted_mul_result.exp); - - auto sig_z {static_cast(z.full_significand())}; - auto exp_z {z.biased_exponent()}; - detail::normalize(sig_z, exp_z); - detail::decimal64_components z_components {sig_z, exp_z, z.isneg()}; - - if (!lhs_bigger) - { - detail::swap(promoted_mul_result, z_components); - abs_lhs_bigger = !abs_lhs_bigger; - } - - detail::decimal64_components result {}; - - if (!promoted_mul_result.sign && z_components.sign) - { - result = detail::d64_sub_impl(promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign, - abs_lhs_bigger); - } - else - { - result = detail::d64_add_impl(promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign); - } - - return {result.sig, result.exp, result.sign}; -} - -constexpr auto fmad64(decimal64 x, decimal64 y, decimal64 z) noexcept -> decimal64 -{ - // First calculate x * y without rounding - constexpr decimal64 zero {0, 0}; - - const auto res {detail::check_non_finite(x, y)}; - if (res != zero) - { - return res; - } - - auto sig_lhs {x.full_significand()}; - auto exp_lhs {x.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {y.full_significand()}; - auto exp_rhs {y.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - auto mul_result {detail::d64_mul_impl(sig_lhs, exp_lhs, x.isneg(), sig_rhs, exp_rhs, y.isneg())}; - const decimal64 dec_result {mul_result.sig, mul_result.exp, mul_result.sign}; - - const auto res_add {detail::check_non_finite(dec_result, z)}; - if (res_add != zero) - { - return res_add; - } - - bool lhs_bigger {dec_result > z}; - if (dec_result.isneg() && z.isneg()) - { - lhs_bigger = !lhs_bigger; - } - bool abs_lhs_bigger {abs(dec_result) > abs(z)}; - - // To avoid the rounding step we promote the constituent pieces to the next higher type - detail::decimal128_components promoted_mul_result {static_cast(mul_result.sig), - mul_result.exp, mul_result.sign}; - - detail::normalize(promoted_mul_result.sig, promoted_mul_result.exp); - - auto sig_z {static_cast(z.full_significand())}; - auto exp_z {z.biased_exponent()}; - detail::normalize(sig_z, exp_z); - detail::decimal128_components z_components {sig_z, exp_z, z.isneg()}; - - if (!lhs_bigger) - { - detail::swap(promoted_mul_result, z_components); - abs_lhs_bigger = !abs_lhs_bigger; - } - - detail::decimal128_components result {}; - - if (!promoted_mul_result.sign && z_components.sign) - { - result = detail::d128_sub_impl( - promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign, - abs_lhs_bigger); - } - else - { - result = detail::d128_add_impl( - promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign); - } - - return {result.sig, result.exp, result.sign}; -} - -constexpr auto fmad128(decimal128 x, decimal128 y, decimal128 z) noexcept -> decimal128 -{ - return x * y + z; -} - -// TODO(mborland): promote to decimal64_fast instead of regular decimal64 once it is available -constexpr auto fmad32f(decimal32_fast x, decimal32_fast y, decimal32_fast z) noexcept -> decimal32_fast -{ - // First calculate x * y without rounding - constexpr decimal32_fast zero {0, 0}; - - const auto res {detail::check_non_finite(x, y)}; - if (res != zero) - { - return res; - } - - auto sig_lhs {x.full_significand()}; - auto exp_lhs {x.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {y.full_significand()}; - auto exp_rhs {y.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - auto mul_result {detail::mul_impl(sig_lhs, exp_lhs, x.isneg(), sig_rhs, exp_rhs, y.isneg())}; - const decimal32_fast dec_result {mul_result.sig, mul_result.exp, mul_result.sign}; - - const auto res_add {detail::check_non_finite(dec_result, z)}; - if (res_add != zero) - { - return res_add; - } - - bool lhs_bigger {dec_result > z}; - if (dec_result.isneg() && z.isneg()) - { - lhs_bigger = !lhs_bigger; - } - bool abs_lhs_bigger {abs(dec_result) > abs(z)}; - - // To avoid the rounding step we promote the constituent pieces to the next higher type - detail::decimal64_components promoted_mul_result {static_cast(mul_result.sig), - mul_result.exp, mul_result.sign}; - - detail::normalize(promoted_mul_result.sig, promoted_mul_result.exp); - - auto sig_z {static_cast(z.full_significand())}; - auto exp_z {z.biased_exponent()}; - detail::normalize(sig_z, exp_z); - detail::decimal64_components z_components {sig_z, exp_z, z.isneg()}; - - if (!lhs_bigger) - { - detail::swap(promoted_mul_result, z_components); - abs_lhs_bigger = !abs_lhs_bigger; - } - - detail::decimal64_components result {}; - - if (!promoted_mul_result.sign && z_components.sign) - { - result = detail::d64_sub_impl(promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign, - abs_lhs_bigger); - } - else - { - result = detail::d64_add_impl(promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign); - } - - return {result.sig, result.exp, result.sign}; -} - -constexpr auto fmad64f(decimal64_fast x, decimal64_fast y, decimal64_fast z) noexcept -> decimal64_fast -{ - // First calculate x * y without rounding - constexpr decimal64_fast zero {0, 0}; - - const auto res {detail::check_non_finite(x, y)}; - if (res != zero) - { - return res; - } - - auto sig_lhs {x.full_significand()}; - auto exp_lhs {x.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {y.full_significand()}; - auto exp_rhs {y.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - auto mul_result {detail::d64_mul_impl(sig_lhs, exp_lhs, x.isneg(), sig_rhs, exp_rhs, y.isneg())}; - const decimal64_fast dec_result {mul_result.sig, mul_result.exp, mul_result.sign}; - - const auto res_add {detail::check_non_finite(dec_result, z)}; - if (res_add != zero) - { - return res_add; - } - - bool lhs_bigger {dec_result > z}; - if (dec_result.isneg() && z.isneg()) - { - lhs_bigger = !lhs_bigger; - } - bool abs_lhs_bigger {abs(dec_result) > abs(z)}; - - // To avoid the rounding step we promote the constituent pieces to the next higher type - detail::decimal128_components promoted_mul_result {static_cast(mul_result.sig), - mul_result.exp, mul_result.sign}; - - detail::normalize(promoted_mul_result.sig, promoted_mul_result.exp); - - auto sig_z {static_cast(z.full_significand())}; - auto exp_z {z.biased_exponent()}; - detail::normalize(sig_z, exp_z); - detail::decimal128_components z_components {sig_z, exp_z, z.isneg()}; - - if (!lhs_bigger) - { - detail::swap(promoted_mul_result, z_components); - abs_lhs_bigger = !abs_lhs_bigger; - } - - detail::decimal128_components result {}; - - if (!promoted_mul_result.sign && z_components.sign) - { - result = detail::d128_sub_impl( - promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign, - abs_lhs_bigger); - } - else - { - result = detail::d128_add_impl( - promoted_mul_result.sig, promoted_mul_result.exp, promoted_mul_result.sign, - z_components.sig, z_components.exp, z_components.sign); - } - - return {result.sig, result.exp, result.sign}; -} - -constexpr auto fmad128f(decimal128_fast x, decimal128_fast y, decimal128_fast z) noexcept -> decimal128_fast -{ - return x * y + z; -} -*/ - BOOST_DECIMAL_EXPORT constexpr auto fma(decimal32 x, decimal32 y, decimal32 z) noexcept -> decimal32 { return x * y + z; diff --git a/include/boost/decimal/detail/config.hpp b/include/boost/decimal/detail/config.hpp index 21798fe96..3dec3b8c2 100644 --- a/include/boost/decimal/detail/config.hpp +++ b/include/boost/decimal/detail/config.hpp @@ -325,4 +325,15 @@ typedef unsigned __int128 uint128_t; # endif #endif +// Since we should not be able to pull these in from the STL in module mode define them ourselves +// This is also low risk since they are not supposed to be exported +#ifdef BOOST_DECIMAL_BUILD_MODULE +# ifndef UINT64_C +# define UINT64_C(x) (x ## ULL) +# endif +# ifndef UINT32_C +# define UINT32_C(x) (x ## UL) +# endif +#endif + #endif // BOOST_DECIMAL_DETAIL_CONFIG_HPP diff --git a/modules/decimal.cxx b/modules/decimal.cxx index 41977a9b2..0031838c2 100644 --- a/modules/decimal.cxx +++ b/modules/decimal.cxx @@ -29,6 +29,7 @@ module; #include #include #include +#include // is a C++23 feature that is not everywhere yet #if __has_include() @@ -123,7 +124,17 @@ struct numeric_limits; // MSVC wants to be imported but also does not support importing it... #ifdef _MSC_VER +# pragma warning( push ) # pragma warning( disable : 5244 ) +#elif defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" #endif #include + +#ifdef _MSC_VER +# pragma warning( pop ) +#elif defined(__clang__) +# pragma clang diagnostic pop +#endif