diff --git a/sprout/complex/nearest.hpp b/sprout/complex/nearest.hpp index 7f715113..0f2858bd 100644 --- a/sprout/complex/nearest.hpp +++ b/sprout/complex/nearest.hpp @@ -22,7 +22,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::complex trunc(sprout::complex const& x) { - return sprout::complex(sprout::trunc(x.real()), sprout::trunc(x.imag())); + return sprout::complex(sprout::math::trunc(x.real()), sprout::math::trunc(x.imag())); } template inline SPROUT_CONSTEXPR sprout::complex diff --git a/sprout/math/acos.hpp b/sprout/math/acos.hpp index 2342e8c3..dc5c71fe 100644 --- a/sprout/math/acos.hpp +++ b/sprout/math/acos.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -45,17 +44,8 @@ namespace sprout { return sprout::math::detail::acos(static_cast(x)); } } // namespace detail - // - // acos - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - acos(ArithmeticType x) { - return sprout::math::detail::acos(x); - } + + using sprout::math::detail::acos; } // namespace math using sprout::math::acos; diff --git a/sprout/math/acosh.hpp b/sprout/math/acosh.hpp index 9d9325a1..38423d86 100644 --- a/sprout/math/acosh.hpp +++ b/sprout/math/acosh.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -45,17 +44,8 @@ namespace sprout { return sprout::math::detail::acosh(static_cast(x)); } } // namespace detail - // - // acosh - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - acosh(ArithmeticType x) { - return sprout::math::detail::acosh(x); - } + + using sprout::math::detail::acosh; } // namespace math using sprout::math::acosh; diff --git a/sprout/math/asin.hpp b/sprout/math/asin.hpp index f55e5d25..f666e420 100644 --- a/sprout/math/asin.hpp +++ b/sprout/math/asin.hpp @@ -14,7 +14,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -66,17 +65,8 @@ namespace sprout { return sprout::math::detail::asin(static_cast(x)); } } // namespace detail - // - // asin - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - asin(ArithmeticType x) { - return sprout::math::detail::asin(x); - } + + using sprout::math::detail::asin; } // namespace math using sprout::math::asin; diff --git a/sprout/math/asinh.hpp b/sprout/math/asinh.hpp index 1d3216d3..0d4db6bc 100644 --- a/sprout/math/asinh.hpp +++ b/sprout/math/asinh.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::asinh(static_cast(x)); } } // namespace detail - // - // asinh - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - asinh(ArithmeticType x) { - return sprout::math::detail::asinh(x); - } + + using sprout::math::detail::asinh; } // namespace math using sprout::math::asinh; diff --git a/sprout/math/atan.hpp b/sprout/math/atan.hpp index 5dec7ffd..250f9c29 100644 --- a/sprout/math/atan.hpp +++ b/sprout/math/atan.hpp @@ -12,7 +12,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -65,17 +64,8 @@ namespace sprout { return sprout::math::detail::atan(static_cast(x)); } } // namespace detail - // - // atan - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - atan(ArithmeticType x) { - return sprout::math::detail::atan(x); - } + + using sprout::math::detail::atan; } // namespace math using sprout::math::atan; diff --git a/sprout/math/atan2.hpp b/sprout/math/atan2.hpp index a8228f5e..749969e6 100644 --- a/sprout/math/atan2.hpp +++ b/sprout/math/atan2.hpp @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include namespace sprout { namespace math { @@ -76,20 +76,8 @@ namespace sprout { return sprout::math::detail::atan2(static_cast(y), static_cast(x)); } } // namespace detail - // - // atan2 - // - template< - typename ArithmeticType1, - typename ArithmeticType2, - typename sprout::enabler_if< - std::is_arithmetic::value && std::is_arithmetic::value - >::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - atan2(ArithmeticType1 y, ArithmeticType2 x) { - return sprout::math::detail::atan2(y, x); - } + + using sprout::math::detail::atan2; } // namespace math using sprout::math::atan2; diff --git a/sprout/math/atanh.hpp b/sprout/math/atanh.hpp index 6d73019d..290bfdd2 100644 --- a/sprout/math/atanh.hpp +++ b/sprout/math/atanh.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -47,17 +46,8 @@ namespace sprout { return sprout::math::detail::atanh(static_cast(x)); } } // namespace detail - // - // atanh - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - atanh(ArithmeticType x) { - return sprout::math::detail::atanh(x); - } + + using sprout::math::detail::atanh; } // namespace math using sprout::math::atanh; diff --git a/sprout/math/cos.hpp b/sprout/math/cos.hpp index 4cdcf4aa..114962b4 100644 --- a/sprout/math/cos.hpp +++ b/sprout/math/cos.hpp @@ -12,7 +12,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -61,17 +60,8 @@ namespace sprout { return sprout::math::detail::cos(static_cast(x)); } } // namespace detail - // - // cos - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - cos(ArithmeticType x) { - return sprout::math::detail::cos(x); - } + + using sprout::math::detail::cos; } // namespace math using sprout::math::cos; diff --git a/sprout/math/cosh.hpp b/sprout/math/cosh.hpp index 6250c431..8ad25913 100644 --- a/sprout/math/cosh.hpp +++ b/sprout/math/cosh.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -59,17 +58,8 @@ namespace sprout { return sprout::math::detail::cosh(static_cast(x)); } } // namespace detail - // - // cosh - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - cosh(ArithmeticType x) { - return sprout::math::detail::cosh(x); - } + + using sprout::math::detail::cosh; } // namespace math using sprout::math::cosh; diff --git a/sprout/math/erf.hpp b/sprout/math/erf.hpp index 04c4c0bf..3778d6c9 100644 --- a/sprout/math/erf.hpp +++ b/sprout/math/erf.hpp @@ -102,13 +102,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR T erf_impl_2_a(T x, T w, T t) { - return sprout::math::detail::erf_impl_2_a_1(x, w, sprout::fractional_part(t), sprout::itrunc(t)); + return sprout::math::detail::erf_impl_2_a_1(x, w, sprout::fractional_part(t), sprout::math::itrunc(t)); } template inline SPROUT_CONSTEXPR T erf_impl_1(T x, T w) { return w < T(2.2) ? sprout::math::detail::erf_impl_2_a(x, w, w * w) - : w < T(6.9) ? sprout::math::detail::erf_impl_2_b(x, w, sprout::fractional_part(w), sprout::itrunc(w) - 2) + : w < T(6.9) ? sprout::math::detail::erf_impl_2_b(x, w, sprout::fractional_part(w), sprout::math::itrunc(w) - 2) : sprout::math::detail::erf_impl_3(x, T(1)) ; } diff --git a/sprout/math/exp.hpp b/sprout/math/exp.hpp index b13443cf..ea560720 100644 --- a/sprout/math/exp.hpp +++ b/sprout/math/exp.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -57,17 +56,8 @@ namespace sprout { return sprout::math::detail::exp(static_cast(x)); } } // namespace detail - // - // exp - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - exp(ArithmeticType x) { - return sprout::math::detail::exp(x); - } + + using sprout::math::detail::exp; } // namespace math using sprout::math::exp; diff --git a/sprout/math/exp10.hpp b/sprout/math/exp10.hpp index c7d3244a..6cb82b12 100644 --- a/sprout/math/exp10.hpp +++ b/sprout/math/exp10.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -41,17 +40,8 @@ namespace sprout { return sprout::math::detail::exp10(static_cast(x)); } } // namespace detail - // - // exp10 - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - exp10(ArithmeticType x) { - return sprout::math::detail::exp10(x); - } + + using sprout::math::detail::exp10; } // namespace math using sprout::math::exp10; diff --git a/sprout/math/exp2.hpp b/sprout/math/exp2.hpp index 2658d41b..67d64f2e 100644 --- a/sprout/math/exp2.hpp +++ b/sprout/math/exp2.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -45,17 +44,8 @@ namespace sprout { return sprout::math::detail::exp2(static_cast(x)); } } // namespace detail - // - // exp2 - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - exp2(ArithmeticType x) { - return sprout::math::detail::exp2(x); - } + + using sprout::math::detail::exp2; } // namespace math using sprout::math::exp2; diff --git a/sprout/math/expm1.hpp b/sprout/math/expm1.hpp index 78a636b8..838e314f 100644 --- a/sprout/math/expm1.hpp +++ b/sprout/math/expm1.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::expm1(static_cast(x)); } } // namespace detail - // - // expm1 - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - expm1(ArithmeticType x) { - return sprout::math::detail::expm1(x); - } + + using sprout::math::detail::expm1; } // namespace math using sprout::math::expm1; diff --git a/sprout/math/float2_exponent.hpp b/sprout/math/float2_exponent.hpp index e8204aee..70bbf5af 100644 --- a/sprout/math/float2_exponent.hpp +++ b/sprout/math/float2_exponent.hpp @@ -18,7 +18,7 @@ namespace sprout { inline SPROUT_CONSTEXPR int float2_exponent(FloatType x) { return x == 0 ? 0 - : sprout::ilogb2(x) + 1 + : sprout::math::ilogb2(x) + 1 ; } diff --git a/sprout/math/float_exponent.hpp b/sprout/math/float_exponent.hpp index 3bd46d00..661dac6e 100644 --- a/sprout/math/float_exponent.hpp +++ b/sprout/math/float_exponent.hpp @@ -18,7 +18,7 @@ namespace sprout { inline SPROUT_CONSTEXPR int float_exponent(FloatType x) { return x == 0 ? 0 - : sprout::ilogb(x) + 1 + : sprout::math::ilogb(x) + 1 ; } diff --git a/sprout/math/fmod.hpp b/sprout/math/fmod.hpp index e10c9f5a..2b8fd467 100644 --- a/sprout/math/fmod.hpp +++ b/sprout/math/fmod.hpp @@ -22,7 +22,7 @@ namespace sprout { ? std::numeric_limits::quiet_NaN() : x == 0 ? FloatType(0) : y == std::numeric_limits::infinity() || y == -std::numeric_limits::infinity() ? x - : x - sprout::trunc(x / y) * y + : x - sprout::math::trunc(x / y) * y ; } diff --git a/sprout/math/fpclassify.hpp b/sprout/math/fpclassify.hpp index afa3dd60..466897c7 100644 --- a/sprout/math/fpclassify.hpp +++ b/sprout/math/fpclassify.hpp @@ -20,9 +20,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR int fpclassify(FloatType x) { - return sprout::isnan(x) ? FP_NAN - : sprout::isinf(x) ? FP_INFINITE - : sprout::iszero(x) ? FP_ZERO + return sprout::math::isnan(x) ? FP_NAN + : sprout::math::isinf(x) ? FP_INFINITE + : sprout::math::iszero(x) ? FP_ZERO : sprout::math::detail::issubnormal_or_zero(x) ? FP_SUBNORMAL : FP_NORMAL ; diff --git a/sprout/math/ilogb.hpp b/sprout/math/ilogb.hpp index 55eaa9e7..a6dcf2d5 100644 --- a/sprout/math/ilogb.hpp +++ b/sprout/math/ilogb.hpp @@ -21,13 +21,16 @@ namespace sprout { > inline SPROUT_CONSTEXPR int ilogb(FloatType x) { - return sprout::iszero(x) ? FP_ILOGB0 - : sprout::isinf(x) ? INT_MAX - : sprout::isnan(x) ? FP_ILOGBNAN - : static_cast(sprout::logb(x)) + return sprout::math::iszero(x) ? FP_ILOGB0 + : sprout::math::isinf(x) ? INT_MAX + : sprout::math::isnan(x) ? FP_ILOGBNAN +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION + : std::ilogb(x) +#else + : static_cast(sprout::math::logb(x)) +#endif ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler @@ -38,7 +41,7 @@ namespace sprout { } } // namespace detail - using NS_SPROUT_MATH_DETAIL::ilogb; + using sprout::math::detail::ilogb; } // namespace math using sprout::math::ilogb; diff --git a/sprout/math/ilogb2.hpp b/sprout/math/ilogb2.hpp index d5e8aae3..2360007e 100644 --- a/sprout/math/ilogb2.hpp +++ b/sprout/math/ilogb2.hpp @@ -26,16 +26,15 @@ namespace sprout { > inline SPROUT_CONSTEXPR int ilogb2(FloatType x) { - return sprout::ilogb(x); + return sprout::math::ilogb(x); } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR int ilogb2(IntType x) { - return sprout::ilogb(x); + return sprout::math::ilogb(x); } #else template< @@ -44,13 +43,12 @@ namespace sprout { > inline SPROUT_CONSTEXPR int ilogb2(FloatType x) { - return sprout::iszero(x) ? FP_ILOGB0 - : sprout::isinf(x) ? INT_MAX - : sprout::isnan(x) ? FP_ILOGBNAN - : static_cast(sprout::logb2(x)) + return sprout::math::iszero(x) ? FP_ILOGB0 + : sprout::math::isinf(x) ? INT_MAX + : sprout::math::isnan(x) ? FP_ILOGBNAN + : static_cast(sprout::math::logb2(x)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/integer_part.hpp b/sprout/math/integer_part.hpp index cec6ffd4..338fa39e 100644 --- a/sprout/math/integer_part.hpp +++ b/sprout/math/integer_part.hpp @@ -20,7 +20,7 @@ namespace sprout { return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : x == std::numeric_limits::quiet_NaN() ? std::numeric_limits::quiet_NaN() - : sprout::trunc(x) + : sprout::math::trunc(x) ; } diff --git a/sprout/math/isfinite.hpp b/sprout/math/isfinite.hpp index c8cbc70f..0228ce8e 100644 --- a/sprout/math/isfinite.hpp +++ b/sprout/math/isfinite.hpp @@ -17,8 +17,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR int isfinite(FloatType x) { - return !sprout::isnan(x) - && !sprout::isinf(x) + return !sprout::math::isnan(x) + && !sprout::math::isinf(x) ; } } // namespace detail diff --git a/sprout/math/isnormal.hpp b/sprout/math/isnormal.hpp index 9d1e33ee..315674c7 100644 --- a/sprout/math/isnormal.hpp +++ b/sprout/math/isnormal.hpp @@ -18,8 +18,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR int isnormal(FloatType x) { - return !sprout::isnan(x) - && !sprout::isinf(x) + return !sprout::math::isnan(x) + && !sprout::math::isinf(x) && !sprout::math::detail::issubnormal_or_zero(x) ; } diff --git a/sprout/math/issubnormal.hpp b/sprout/math/issubnormal.hpp index 8e182194..a1bfc955 100644 --- a/sprout/math/issubnormal.hpp +++ b/sprout/math/issubnormal.hpp @@ -28,7 +28,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR int issubnormal(FloatType x) { - return !sprout::iszero(x) + return !sprout::math::iszero(x) && sprout::math::detail::issubnormal_or_zero(x) ; } diff --git a/sprout/math/itrunc.hpp b/sprout/math/itrunc.hpp index 1857f384..d0e0f6a4 100644 --- a/sprout/math/itrunc.hpp +++ b/sprout/math/itrunc.hpp @@ -30,7 +30,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR To itrunc(FloatType x) { - return sprout::math::detail::itrunc_impl(sprout::trunc(x)); + return sprout::math::detail::itrunc_impl(sprout::math::trunc(x)); } #else template< diff --git a/sprout/math/ldexp.hpp b/sprout/math/ldexp.hpp index 9804ee67..8eda68c6 100644 --- a/sprout/math/ldexp.hpp +++ b/sprout/math/ldexp.hpp @@ -5,26 +5,33 @@ #include #include #include +#include +#include #include #include namespace sprout { namespace math { namespace detail { + template + inline SPROUT_CONSTEXPR T + ldexp_impl(T x, int exp) { + return x * sprout::detail::pow_n(T(2), exp); + } + template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType ldexp(FloatType x, int exp) { - return x == 0 ? FloatType(0) - : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : exp == 0 ? x - : x * sprout::detail::pow_n(FloatType(2), exp) + : x == 0 ? sprout::math::copysign(FloatType(0), x) + : static_cast(sprout::math::detail::ldexp_impl(static_cast::type>(x), exp)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/lgamma.hpp b/sprout/math/lgamma.hpp index 811aaf20..1b9ef81b 100644 --- a/sprout/math/lgamma.hpp +++ b/sprout/math/lgamma.hpp @@ -138,7 +138,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR T lgamma_impl_2_b(T x, T w, T t) { - return sprout::math::detail::lgamma_impl_2_b_1(x, w, t, sprout::itrunc(t) + 4); + return sprout::math::detail::lgamma_impl_2_b_1(x, w, t, sprout::math::itrunc(t) + 4); } template inline SPROUT_CONSTEXPR T @@ -165,7 +165,7 @@ namespace sprout { lgamma_impl_1(T x, T w) { return w < T(0.5) ? sprout::math::detail::lgamma_impl_2_a(x, w, w < T(0.25) ? 0 : 1) : w < T(3.5) ? sprout::math::detail::lgamma_impl_2_b(x, w, w - T(4.5) / (w + T(0.5))) - : w < T(8) ? sprout::math::detail::lgamma_impl_2_c(x, w, sprout::itrunc(w) - 3) + : w < T(8) ? sprout::math::detail::lgamma_impl_2_c(x, w, sprout::math::itrunc(w) - 3) : sprout::math::detail::lgamma_impl_2_d(x, w, T(1) / w) ; } diff --git a/sprout/math/log.hpp b/sprout/math/log.hpp index 2ff222da..9cd58059 100644 --- a/sprout/math/log.hpp +++ b/sprout/math/log.hpp @@ -12,7 +12,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -68,17 +67,8 @@ namespace sprout { return sprout::math::detail::log(static_cast(x)); } } // namespace detail - // - // log - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - log(ArithmeticType x) { - return sprout::math::detail::log(x); - } + + using sprout::math::detail::log; } // namespace math using sprout::math::log; diff --git a/sprout/math/log10.hpp b/sprout/math/log10.hpp index 3c349c09..615dc6bf 100644 --- a/sprout/math/log10.hpp +++ b/sprout/math/log10.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::log10(static_cast(x)); } } // namespace detail - // - // log10 - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - log10(ArithmeticType x) { - return sprout::math::detail::log10(x); - } + + using sprout::math::detail::log10; } // namespace math using sprout::math::log10; diff --git a/sprout/math/log1p.hpp b/sprout/math/log1p.hpp index d9a633fb..cad4e88d 100644 --- a/sprout/math/log1p.hpp +++ b/sprout/math/log1p.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::log1p(static_cast(x)); } } // namespace detail - // - // log1p - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - log1p(ArithmeticType x) { - return sprout::math::detail::log1p(x); - } + + using sprout::math::detail::log1p; } // namespace math using sprout::math::log1p; diff --git a/sprout/math/log2.hpp b/sprout/math/log2.hpp index 698f360c..f54b5304 100644 --- a/sprout/math/log2.hpp +++ b/sprout/math/log2.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::log2(static_cast(x)); } } // namespace detail - // - // log2 - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - log2(ArithmeticType x) { - return sprout::math::detail::log2(x); - } + + using sprout::math::detail::log2; } // namespace math using sprout::math::log2; diff --git a/sprout/math/log_a.hpp b/sprout/math/log_a.hpp index 8de92409..65c90368 100644 --- a/sprout/math/log_a.hpp +++ b/sprout/math/log_a.hpp @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include namespace sprout { namespace math { diff --git a/sprout/math/logb.hpp b/sprout/math/logb.hpp index 0e42f30f..209c4a07 100644 --- a/sprout/math/logb.hpp +++ b/sprout/math/logb.hpp @@ -5,20 +5,22 @@ #include #include #include -#include #include +#include +#include #include #include #include #include +#include namespace sprout { namespace math { namespace detail { template inline SPROUT_CONSTEXPR T - logb_impl_2_neg_lo(T x, T x0, T base, T exp) { - return base < 1 ? sprout::math::detail::logb_impl_2_neg_lo( + logb_impl_3_neg_lo(T x, T x0, T base, T exp) { + return base < 1 ? sprout::math::detail::logb_impl_3_neg_lo( x, x0 * std::numeric_limits::radix, x / (x0 / std::numeric_limits::radix), exp - 1 ) : exp @@ -26,8 +28,8 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb_impl_2_neg_hi(T x, T x0, T base, T exp) { - return !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_2_neg_hi( + logb_impl_3_neg_hi(T x, T x0, T base, T exp) { + return !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_3_neg_hi( x, x0 / std::numeric_limits::radix, x / (x0 * std::numeric_limits::radix), exp + 1 ) : exp @@ -35,8 +37,8 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb_impl_2_pos_lo(T x, T x0, T base, T exp) { - return base < 1 ? sprout::math::detail::logb_impl_2_pos_lo( + logb_impl_3_pos_lo(T x, T x0, T base, T exp) { + return base < 1 ? sprout::math::detail::logb_impl_3_pos_lo( x, x0 * std::numeric_limits::radix, x / (x0 / std::numeric_limits::radix), exp + 1 ) : exp @@ -44,8 +46,8 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb_impl_2_pos_hi(T x, T x0, T base, T exp) { - return !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_2_pos_hi( + logb_impl_3_pos_hi(T x, T x0, T base, T exp) { + return !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_3_pos_hi( x, x0 / std::numeric_limits::radix, x / (x0 * std::numeric_limits::radix), exp - 1 ) : exp @@ -53,36 +55,43 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb_impl_2(T x, T x0, T base, T exp) { - return exp < 0 - ? base < 1 ? sprout::math::detail::logb_impl_2_neg_lo( + logb_impl_3(T x, T x0, T base, T exp) { + return x < 1 + ? base < 1 ? sprout::math::detail::logb_impl_3_neg_lo( x, x0 * std::numeric_limits::radix, x / (x0 / std::numeric_limits::radix), exp - 1 ) - : !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_2_neg_hi( - x, x0 / std::numeric_limits::radix, x / (x0 * std::numeric_limits::radix), exp + 1 - ) + : !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_3_neg_hi( + x, x0 / std::numeric_limits::radix, x / (x0 * std::numeric_limits::radix), exp + 1 + ) : exp - : base < 1 ? sprout::math::detail::logb_impl_2_pos_lo( + : base < 1 ? sprout::math::detail::logb_impl_3_pos_lo( x, x0 * std::numeric_limits::radix, x / (x0 / std::numeric_limits::radix), exp + 1 ) - : !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_2_pos_hi( - x, x0 / std::numeric_limits::radix, x / (x0 * std::numeric_limits::radix), exp - 1 - ) + : !(base < std::numeric_limits::radix) ? sprout::math::detail::logb_impl_3_pos_hi( + x, x0 / std::numeric_limits::radix, x / (x0 * std::numeric_limits::radix), exp - 1 + ) : exp ; } template inline SPROUT_CONSTEXPR T - logb_impl_1(T x, T x0, T exp) { - return sprout::math::detail::logb_impl_2(x, x0, x / x0, exp); + logb_impl_2(T x, T x0, T exp) { + return sprout::math::detail::logb_impl_3(x, x0, x / x0, exp); } template inline SPROUT_CONSTEXPR T - logb_impl(T x, T exp) { - return sprout::math::detail::logb_impl_1( - x, sprout::detail::pow_n(T(std::numeric_limits::radix), sprout::itrunc(exp)), exp + logb_impl_1(T x, T exp) { + return sprout::math::detail::logb_impl_2( + x, sprout::detail::pow_n(T(std::numeric_limits::radix), sprout::math::itrunc(exp)), exp ); } + template + inline SPROUT_CONSTEXPR T + logb_impl(T x) { + return x < 0 ? sprout::math::detail::logb_impl_1(-x, sprout::math::trunc(sprout::math::log_a(T(std::numeric_limits::radix), -x))) + : sprout::math::detail::logb_impl_1(x, sprout::math::trunc(sprout::math::log_a(T(std::numeric_limits::radix), x))) + ; + } template< typename FloatType, @@ -91,13 +100,15 @@ namespace sprout { inline SPROUT_CONSTEXPR FloatType logb(FloatType x) { return x == 0 ? -std::numeric_limits::infinity() +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION + : std::logb(x) +#else : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? std::numeric_limits::infinity() - : x < 0 ? sprout::math::detail::logb_impl(-x, sprout::trunc(sprout::log_a(FloatType(std::numeric_limits::radix), -x))) - : sprout::math::detail::logb_impl(x, sprout::trunc(sprout::log_a(FloatType(std::numeric_limits::radix), x))) + : static_cast(sprout::math::detail::logb_impl(static_cast::type>(x))) +#endif ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler @@ -108,7 +119,7 @@ namespace sprout { } } // namespace detail - using NS_SPROUT_MATH_DETAIL::logb; + using sprout::math::detail::logb; } // namespace math using sprout::math::logb; diff --git a/sprout/math/logb2.hpp b/sprout/math/logb2.hpp index fd0f21e2..87ff5595 100644 --- a/sprout/math/logb2.hpp +++ b/sprout/math/logb2.hpp @@ -1,17 +1,18 @@ #ifndef SPROUT_MATH_LOGB2_HPP #define SPROUT_MATH_LOGB2_HPP -#include #include #include #include #include +#include #if SPROUT_FLT_RADIX_IS_2 # include #else # include # include # include +# include # include # include # include @@ -27,22 +28,21 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType logb2(FloatType x) { - return sprout::logb(x); + return sprout::math::logb(x); } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR double logb2(IntType x) { - return sprout::logb(x); + return sprout::math::logb(x); } #else template inline SPROUT_CONSTEXPR T - logb2_impl_2_neg_lo(T x, T x0, T base, T exp) { - return base < 1 ? sprout::math::detail::logb2_impl_2_neg_lo( + logb2_impl_3_neg_lo(T x, T x0, T base, T exp) { + return base < 1 ? sprout::math::detail::logb2_impl_3_neg_lo( x, x0 * 2, x / (x0 / 2), exp - 1 ) : exp @@ -50,8 +50,8 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb2_impl_2_neg_hi(T x, T x0, T base, T exp) { - return !(base < 2) ? sprout::math::detail::logb2_impl_2_neg_hi( + logb2_impl_3_neg_hi(T x, T x0, T base, T exp) { + return !(base < 2) ? sprout::math::detail::logb2_impl_3_neg_hi( x, x0 / 2, x / (x0 * 2), exp + 1 ) : exp @@ -59,8 +59,8 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb2_impl_2_pos_lo(T x, T x0, T base, T exp) { - return base < 1 ? sprout::math::detail::logb2_impl_2_pos_lo( + logb2_impl_3_pos_lo(T x, T x0, T base, T exp) { + return base < 1 ? sprout::math::detail::logb2_impl_3_pos_lo( x, x0 * 2, x / (x0 / 2), exp + 1 ) : exp @@ -68,8 +68,8 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb2_impl_2_pos_hi(T x, T x0, T base, T exp) { - return !(base < 2) ? sprout::math::detail::logb2_impl_2_pos_hi( + logb2_impl_3_pos_hi(T x, T x0, T base, T exp) { + return !(base < 2) ? sprout::math::detail::logb2_impl_3_pos_hi( x, x0 / 2, x / (x0 * 2), exp - 1 ) : exp @@ -77,19 +77,19 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb2_impl_2(T x, T x0, T base, T exp) { - return exp < 0 - ? base < 1 ? sprout::math::detail::logb2_impl_2_neg_lo( + logb2_impl_3(T x, T x0, T base, T exp) { + return x < 1 + ? base < 1 ? sprout::math::detail::logb2_impl_3_neg_lo( x, x0 * 2, x / (x0 / 2), exp - 1 ) - : !(base < 2) ? sprout::math::detail::logb2_impl_2_neg_hi( + : !(base < 2) ? sprout::math::detail::logb2_impl_3_neg_hi( x, x0 / 2, x / (x0 * 2), exp + 1 ) : exp - : base < 1 ? sprout::math::detail::logb2_impl_2_pos_lo( + : base < 1 ? sprout::math::detail::logb2_impl_3_pos_lo( x, x0 * 2, x / (x0 / 2), exp + 1 ) - : !(base < 2) ? sprout::math::detail::logb2_impl_2_pos_hi( + : !(base < 2) ? sprout::math::detail::logb2_impl_3_pos_hi( x, x0 / 2, x / (x0 * 2), exp - 1 ) : exp @@ -97,16 +97,23 @@ namespace sprout { } template inline SPROUT_CONSTEXPR T - logb2_impl_1(T x, T x0, T exp) { - return sprout::math::detail::logb2_impl_2(x, x0, x / x0, exp); + logb2_impl_2(T x, T x0, T exp) { + return sprout::math::detail::logb2_impl_3(x, x0, x / x0, exp); } template inline SPROUT_CONSTEXPR T - logb2_impl(T x, T exp) { - return sprout::math::detail::logb2_impl_1( - x, sprout::detail::pow_n(T(2), sprout::itrunc(exp)), exp + logb2_impl_1(T x, T exp) { + return sprout::math::detail::logb2_impl_2( + x, sprout::detail::pow_n(T(2), sprout::math::itrunc(exp)), exp ); } + template + inline SPROUT_CONSTEXPR T + logb2_impl(T x) { + return x < 0 ? sprout::math::detail::logb2_impl_1(-x, sprout::math::trunc(sprout::math::log_a(T(2), -x))) + : sprout::math::detail::logb2_impl_1(x, sprout::math::trunc(sprout::math::log_a(T(2), x))) + ; + } template< typename FloatType, @@ -117,11 +124,9 @@ namespace sprout { return x == 0 ? -std::numeric_limits::infinity() : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? std::numeric_limits::infinity() - : x < 0 ? sprout::math::detail::logb2_impl(-x, sprout::trunc(sprout::log_a(FloatType(2), -x))) - : sprout::math::detail::logb2_impl(x, sprout::trunc(sprout::log_a(FloatType(2), x))) + : static_cast(sprout::math::detail::logb2_impl(static_cast::type>(x))) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/scalbln.hpp b/sprout/math/scalbln.hpp index a21e63a6..f9d757d7 100644 --- a/sprout/math/scalbln.hpp +++ b/sprout/math/scalbln.hpp @@ -5,26 +5,33 @@ #include #include #include +#include +#include #include #include namespace sprout { namespace math { namespace detail { + template + inline SPROUT_CONSTEXPR T + scalbln_impl(T x, long exp) { + return x * sprout::detail::pow_n(T(std::numeric_limits::radix), exp); + } + template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType scalbln(FloatType x, long exp) { - return x == 0 ? FloatType(0) - : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : exp == 0 ? x - : x * sprout::detail::pow_n(FloatType(std::numeric_limits::radix), exp) + : x == 0 ? sprout::math::copysign(FloatType(0), x) + : static_cast(sprout::math::detail::scalbln_impl(static_cast::type>(x), exp)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/scalbn.hpp b/sprout/math/scalbn.hpp index f8f7f9b8..2309b9fa 100644 --- a/sprout/math/scalbn.hpp +++ b/sprout/math/scalbn.hpp @@ -5,26 +5,33 @@ #include #include #include +#include +#include #include #include namespace sprout { namespace math { namespace detail { + template + inline SPROUT_CONSTEXPR T + scalbn_impl(T x, int exp) { + return x * sprout::detail::pow_n(T(std::numeric_limits::radix), exp); + } + template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType scalbn(FloatType x, int exp) { - return x == 0 ? FloatType(0) - : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : exp == 0 ? x - : x * sprout::detail::pow_n(FloatType(std::numeric_limits::radix), exp) + : x == 0 ? sprout::math::copysign(FloatType(0), x) + : static_cast(sprout::math::detail::scalbn_impl(static_cast::type>(x), exp)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/sin.hpp b/sprout/math/sin.hpp index 4e44a1a8..c6dcaf85 100644 --- a/sprout/math/sin.hpp +++ b/sprout/math/sin.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -47,17 +46,8 @@ namespace sprout { return sprout::math::detail::sin(static_cast(x)); } } // namespace detail - // - // sin - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - sin(ArithmeticType x) { - return sprout::math::detail::sin(x); - } + + using sprout::math::detail::sin; } // namespace math using sprout::math::sin; diff --git a/sprout/math/sinh.hpp b/sprout/math/sinh.hpp index a9a51555..1cdf4a3d 100644 --- a/sprout/math/sinh.hpp +++ b/sprout/math/sinh.hpp @@ -11,7 +11,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -59,17 +58,8 @@ namespace sprout { return sprout::math::detail::sinh(static_cast(x)); } } // namespace detail - // - // sinh - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - sinh(ArithmeticType x) { - return sprout::math::detail::sinh(x); - } + + using sprout::math::detail::sinh; } // namespace math using sprout::math::sinh; diff --git a/sprout/math/tan.hpp b/sprout/math/tan.hpp index 51a1dbf6..4d29f769 100644 --- a/sprout/math/tan.hpp +++ b/sprout/math/tan.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::tan(static_cast(x)); } } // namespace detail - // - // tan - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - tan(ArithmeticType x) { - return sprout::math::detail::tan(x); - } + + using sprout::math::detail::tan; } // namespace math using sprout::math::tan; diff --git a/sprout/math/tanh.hpp b/sprout/math/tanh.hpp index c0f7bc0c..f3e32f11 100644 --- a/sprout/math/tanh.hpp +++ b/sprout/math/tanh.hpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace sprout { namespace math { @@ -46,17 +45,8 @@ namespace sprout { return sprout::math::detail::tanh(static_cast(x)); } } // namespace detail - // - // tanh - // - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - tanh(ArithmeticType x) { - return sprout::math::detail::tanh(x); - } + + using sprout::math::detail::tanh; } // namespace math using sprout::math::tanh;