fix exponential functions

This commit is contained in:
bolero-MURAKAMI 2013-04-25 15:36:19 +09:00
parent 32c3ba02d4
commit dad3acceea
41 changed files with 180 additions and 354 deletions

View file

@ -22,7 +22,7 @@ namespace sprout {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
trunc(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::trunc(x.real()), sprout::trunc(x.imag()));
return sprout::complex<T>(sprout::math::trunc(x.real()), sprout::math::trunc(x.imag()));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>

View file

@ -10,7 +10,6 @@
#include <sprout/math/fabs.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -45,17 +44,8 @@ namespace sprout {
return sprout::math::detail::acos(static_cast<double>(x));
}
} // namespace detail
//
// acos
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
acos(ArithmeticType x) {
return sprout::math::detail::acos(x);
}
using sprout::math::detail::acos;
} // namespace math
using sprout::math::acos;

View file

@ -9,7 +9,6 @@
#include <sprout/math/log.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -45,17 +44,8 @@ namespace sprout {
return sprout::math::detail::acosh(static_cast<double>(x));
}
} // namespace detail
//
// acosh
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
acosh(ArithmeticType x) {
return sprout::math::detail::acosh(x);
}
using sprout::math::detail::acosh;
} // namespace math
using sprout::math::acosh;

View file

@ -14,7 +14,6 @@
#include <sprout/math/fabs.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -66,17 +65,8 @@ namespace sprout {
return sprout::math::detail::asin(static_cast<double>(x));
}
} // namespace detail
//
// asin
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
asin(ArithmeticType x) {
return sprout::math::detail::asin(x);
}
using sprout::math::detail::asin;
} // namespace math
using sprout::math::asin;

View file

@ -10,7 +10,6 @@
#include <sprout/math/log.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::asinh(static_cast<double>(x));
}
} // namespace detail
//
// asinh
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
asinh(ArithmeticType x) {
return sprout::math::detail::asinh(x);
}
using sprout::math::detail::asinh;
} // namespace math
using sprout::math::asinh;

View file

@ -12,7 +12,6 @@
#include <sprout/math/factorial.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -65,17 +64,8 @@ namespace sprout {
return sprout::math::detail::atan(static_cast<double>(x));
}
} // namespace detail
//
// atan
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
atan(ArithmeticType x) {
return sprout::math::detail::atan(x);
}
using sprout::math::detail::atan;
} // namespace math
using sprout::math::atan;

View file

@ -10,8 +10,8 @@
#include <sprout/math/copysign.hpp>
#include <sprout/math/signbit.hpp>
#include <sprout/math/atan.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
@ -76,20 +76,8 @@ namespace sprout {
return sprout::math::detail::atan2(static_cast<type>(y), static_cast<type>(x));
}
} // namespace detail
//
// atan2
//
template<
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type
atan2(ArithmeticType1 y, ArithmeticType2 x) {
return sprout::math::detail::atan2(y, x);
}
using sprout::math::detail::atan2;
} // namespace math
using sprout::math::atan2;

View file

@ -10,7 +10,6 @@
#include <sprout/math/log.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -47,17 +46,8 @@ namespace sprout {
return sprout::math::detail::atanh(static_cast<double>(x));
}
} // namespace detail
//
// atanh
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
atanh(ArithmeticType x) {
return sprout::math::detail::atanh(x);
}
using sprout::math::detail::atanh;
} // namespace math
using sprout::math::atanh;

View file

@ -12,7 +12,6 @@
#include <sprout/math/constants.hpp>
#include <sprout/math/fmod.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -61,17 +60,8 @@ namespace sprout {
return sprout::math::detail::cos(static_cast<double>(x));
}
} // namespace detail
//
// cos
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
cos(ArithmeticType x) {
return sprout::math::detail::cos(x);
}
using sprout::math::detail::cos;
} // namespace math
using sprout::math::cos;

View file

@ -10,7 +10,6 @@
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -59,17 +58,8 @@ namespace sprout {
return sprout::math::detail::cosh(static_cast<double>(x));
}
} // namespace detail
//
// cosh
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
cosh(ArithmeticType x) {
return sprout::math::detail::cosh(x);
}
using sprout::math::detail::cosh;
} // namespace math
using sprout::math::cosh;

View file

@ -102,13 +102,13 @@ namespace sprout {
template<typename T>
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<typename T>
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))
;
}

View file

@ -10,7 +10,6 @@
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -57,17 +56,8 @@ namespace sprout {
return sprout::math::detail::exp(static_cast<double>(x));
}
} // namespace detail
//
// exp
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
exp(ArithmeticType x) {
return sprout::math::detail::exp(x);
}
using sprout::math::detail::exp;
} // namespace math
using sprout::math::exp;

View file

@ -9,7 +9,6 @@
#include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -41,17 +40,8 @@ namespace sprout {
return sprout::math::detail::exp10(static_cast<double>(x));
}
} // namespace detail
//
// exp10
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
exp10(ArithmeticType x) {
return sprout::math::detail::exp10(x);
}
using sprout::math::detail::exp10;
} // namespace math
using sprout::math::exp10;

View file

@ -9,7 +9,6 @@
#include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -45,17 +44,8 @@ namespace sprout {
return sprout::math::detail::exp2(static_cast<double>(x));
}
} // namespace detail
//
// exp2
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
exp2(ArithmeticType x) {
return sprout::math::detail::exp2(x);
}
using sprout::math::detail::exp2;
} // namespace math
using sprout::math::exp2;

View file

@ -10,7 +10,6 @@
#include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::expm1(static_cast<double>(x));
}
} // namespace detail
//
// expm1
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
expm1(ArithmeticType x) {
return sprout::math::detail::expm1(x);
}
using sprout::math::detail::expm1;
} // namespace math
using sprout::math::expm1;

View file

@ -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
;
}

View file

@ -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
;
}

View file

@ -22,7 +22,7 @@ namespace sprout {
? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x
: x - sprout::trunc(x / y) * y
: x - sprout::math::trunc(x / y) * y
;
}

View file

@ -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
;

View file

@ -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<int>(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<int>(sprout::math::logb(x))
#endif
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::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;

View file

@ -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<std::is_integral<IntType>::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<int>(sprout::logb2(x))
return sprout::math::iszero(x) ? FP_ILOGB0
: sprout::math::isinf(x) ? INT_MAX
: sprout::math::isnan(x) ? FP_ILOGBNAN
: static_cast<int>(sprout::math::logb2(x))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -20,7 +20,7 @@ namespace sprout {
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::trunc(x)
: sprout::math::trunc(x)
;
}

View file

@ -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

View file

@ -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)
;
}

View file

@ -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)
;
}

View file

@ -30,7 +30,7 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR To
itrunc(FloatType x) {
return sprout::math::detail::itrunc_impl<To>(sprout::trunc(x));
return sprout::math::detail::itrunc_impl<To>(sprout::math::trunc(x));
}
#else
template<

View file

@ -5,26 +5,33 @@
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename T>
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<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
ldexp(FloatType x, int exp) {
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x
: x * sprout::detail::pow_n(FloatType(2), exp)
: x == 0 ? sprout::math::copysign(FloatType(0), x)
: static_cast<FloatType>(sprout::math::detail::ldexp_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x), exp))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -138,7 +138,7 @@ namespace sprout {
template<typename T>
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<typename T>
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)
;
}

View file

@ -12,7 +12,6 @@
#include <sprout/math/factorial.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -68,17 +67,8 @@ namespace sprout {
return sprout::math::detail::log(static_cast<double>(x));
}
} // namespace detail
//
// log
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
log(ArithmeticType x) {
return sprout::math::detail::log(x);
}
using sprout::math::detail::log;
} // namespace math
using sprout::math::log;

View file

@ -9,7 +9,6 @@
#include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::log10(static_cast<double>(x));
}
} // namespace detail
//
// log10
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
log10(ArithmeticType x) {
return sprout::math::detail::log10(x);
}
using sprout::math::detail::log10;
} // namespace math
using sprout::math::log10;

View file

@ -9,7 +9,6 @@
#include <sprout/math/copysign.hpp>
#include <sprout/math/log.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::log1p(static_cast<double>(x));
}
} // namespace detail
//
// log1p
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
log1p(ArithmeticType x) {
return sprout::math::detail::log1p(x);
}
using sprout::math::detail::log1p;
} // namespace math
using sprout::math::log1p;

View file

@ -9,7 +9,6 @@
#include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::log2(static_cast<double>(x));
}
} // namespace detail
//
// log2
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
log2(ArithmeticType x) {
return sprout::math::detail::log2(x);
}
using sprout::math::detail::log2;
} // namespace math
using sprout::math::log2;

View file

@ -6,8 +6,8 @@
#include <sprout/math/detail/config.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {

View file

@ -5,20 +5,22 @@
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/log_a.hpp>
#include <sprout/math/trunc.hpp>
#include <sprout/math/itrunc.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename T>
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<T>::radix, x / (x0 / std::numeric_limits<T>::radix), exp - 1
)
: exp
@ -26,8 +28,8 @@ namespace sprout {
}
template<typename T>
inline SPROUT_CONSTEXPR T
logb_impl_2_neg_hi(T x, T x0, T base, T exp) {
return !(base < std::numeric_limits<T>::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<T>::radix) ? sprout::math::detail::logb_impl_3_neg_hi(
x, x0 / std::numeric_limits<T>::radix, x / (x0 * std::numeric_limits<T>::radix), exp + 1
)
: exp
@ -35,8 +37,8 @@ namespace sprout {
}
template<typename T>
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<T>::radix, x / (x0 / std::numeric_limits<T>::radix), exp + 1
)
: exp
@ -44,8 +46,8 @@ namespace sprout {
}
template<typename T>
inline SPROUT_CONSTEXPR T
logb_impl_2_pos_hi(T x, T x0, T base, T exp) {
return !(base < std::numeric_limits<T>::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<T>::radix) ? sprout::math::detail::logb_impl_3_pos_hi(
x, x0 / std::numeric_limits<T>::radix, x / (x0 * std::numeric_limits<T>::radix), exp - 1
)
: exp
@ -53,36 +55,43 @@ namespace sprout {
}
template<typename T>
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<T>::radix, x / (x0 / std::numeric_limits<T>::radix), exp - 1
)
: !(base < std::numeric_limits<T>::radix) ? sprout::math::detail::logb_impl_2_neg_hi(
x, x0 / std::numeric_limits<T>::radix, x / (x0 * std::numeric_limits<T>::radix), exp + 1
)
: !(base < std::numeric_limits<T>::radix) ? sprout::math::detail::logb_impl_3_neg_hi(
x, x0 / std::numeric_limits<T>::radix, x / (x0 * std::numeric_limits<T>::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<T>::radix, x / (x0 / std::numeric_limits<T>::radix), exp + 1
)
: !(base < std::numeric_limits<T>::radix) ? sprout::math::detail::logb_impl_2_pos_hi(
x, x0 / std::numeric_limits<T>::radix, x / (x0 * std::numeric_limits<T>::radix), exp - 1
)
: !(base < std::numeric_limits<T>::radix) ? sprout::math::detail::logb_impl_3_pos_hi(
x, x0 / std::numeric_limits<T>::radix, x / (x0 * std::numeric_limits<T>::radix), exp - 1
)
: exp
;
}
template<typename T>
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<typename T>
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<T>::radix), sprout::itrunc<std::intmax_t>(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<T>::radix), sprout::math::itrunc<std::intmax_t>(exp)), exp
);
}
template<typename T>
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<T>::radix), -x)))
: sprout::math::detail::logb_impl_1(x, sprout::math::trunc(sprout::math::log_a(T(std::numeric_limits<T>::radix), x)))
;
}
template<
typename FloatType,
@ -91,13 +100,15 @@ namespace sprout {
inline SPROUT_CONSTEXPR FloatType
logb(FloatType x) {
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::logb(x)
#else
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity()
: x < 0 ? sprout::math::detail::logb_impl(-x, sprout::trunc(sprout::log_a(FloatType(std::numeric_limits<FloatType>::radix), -x)))
: sprout::math::detail::logb_impl(x, sprout::trunc(sprout::log_a(FloatType(std::numeric_limits<FloatType>::radix), x)))
: static_cast<FloatType>(sprout::math::detail::logb_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
#endif
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::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;

View file

@ -1,17 +1,18 @@
#ifndef SPROUT_MATH_LOGB2_HPP
#define SPROUT_MATH_LOGB2_HPP
#include <cstdint>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
#if SPROUT_FLT_RADIX_IS_2
# include <sprout/math/logb.hpp>
#else
# include <cstdint>
# include <limits>
# include <sprout/detail/pow.hpp>
# include <sprout/math/detail/float_compute.hpp>
# include <sprout/math/log_a.hpp>
# include <sprout/math/trunc.hpp>
# include <sprout/math/itrunc.hpp>
@ -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<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
logb2(IntType x) {
return sprout::logb(x);
return sprout::math::logb(x);
}
#else
template<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<std::intmax_t>(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<std::intmax_t>(exp)), exp
);
}
template<typename T>
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<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::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<FloatType>(sprout::math::detail::logb2_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -5,26 +5,33 @@
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename FloatType, typename T>
inline SPROUT_CONSTEXPR T
scalbln_impl(T x, long exp) {
return x * sprout::detail::pow_n(T(std::numeric_limits<FloatType>::radix), exp);
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
scalbln(FloatType x, long exp) {
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x
: x * sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), exp)
: x == 0 ? sprout::math::copysign(FloatType(0), x)
: static_cast<FloatType>(sprout::math::detail::scalbln_impl<FloatType>(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x), exp))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -5,26 +5,33 @@
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename FloatType, typename T>
inline SPROUT_CONSTEXPR T
scalbn_impl(T x, int exp) {
return x * sprout::detail::pow_n(T(std::numeric_limits<FloatType>::radix), exp);
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
scalbn(FloatType x, int exp) {
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x
: x * sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), exp)
: x == 0 ? sprout::math::copysign(FloatType(0), x)
: static_cast<FloatType>(sprout::math::detail::scalbn_impl<FloatType>(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x), exp))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -10,7 +10,6 @@
#include <sprout/math/copysign.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -47,17 +46,8 @@ namespace sprout {
return sprout::math::detail::sin(static_cast<double>(x));
}
} // namespace detail
//
// sin
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
sin(ArithmeticType x) {
return sprout::math::detail::sin(x);
}
using sprout::math::detail::sin;
} // namespace math
using sprout::math::sin;

View file

@ -11,7 +11,6 @@
#include <sprout/math/copysign.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -59,17 +58,8 @@ namespace sprout {
return sprout::math::detail::sinh(static_cast<double>(x));
}
} // namespace detail
//
// sinh
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
sinh(ArithmeticType x) {
return sprout::math::detail::sinh(x);
}
using sprout::math::detail::sinh;
} // namespace math
using sprout::math::sinh;

View file

@ -10,7 +10,6 @@
#include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::tan(static_cast<double>(x));
}
} // namespace detail
//
// tan
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
tan(ArithmeticType x) {
return sprout::math::detail::tan(x);
}
using sprout::math::detail::tan;
} // namespace math
using sprout::math::tan;

View file

@ -10,7 +10,6 @@
#include <sprout/math/sinh.hpp>
#include <sprout/math/cosh.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::tanh(static_cast<double>(x));
}
} // namespace detail
//
// tanh
//
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
tanh(ArithmeticType x) {
return sprout::math::detail::tanh(x);
}
using sprout::math::detail::tanh;
} // namespace math
using sprout::math::tanh;