1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-02-04 21:33:56 +00:00

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> template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> inline SPROUT_CONSTEXPR sprout::complex<T>
trunc(sprout::complex<T> const& x) { 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> template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> inline SPROUT_CONSTEXPR sprout::complex<T>

View file

@ -10,7 +10,6 @@
#include <sprout/math/fabs.hpp> #include <sprout/math/fabs.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -45,17 +44,8 @@ namespace sprout {
return sprout::math::detail::acos(static_cast<double>(x)); return sprout::math::detail::acos(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// acos using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::acos; using sprout::math::acos;

View file

@ -9,7 +9,6 @@
#include <sprout/math/log.hpp> #include <sprout/math/log.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -45,17 +44,8 @@ namespace sprout {
return sprout::math::detail::acosh(static_cast<double>(x)); return sprout::math::detail::acosh(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// acosh using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::acosh; using sprout::math::acosh;

View file

@ -14,7 +14,6 @@
#include <sprout/math/fabs.hpp> #include <sprout/math/fabs.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -66,17 +65,8 @@ namespace sprout {
return sprout::math::detail::asin(static_cast<double>(x)); return sprout::math::detail::asin(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// asin using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::asin; using sprout::math::asin;

View file

@ -10,7 +10,6 @@
#include <sprout/math/log.hpp> #include <sprout/math/log.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::asinh(static_cast<double>(x)); return sprout::math::detail::asinh(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// asinh using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::asinh; using sprout::math::asinh;

View file

@ -12,7 +12,6 @@
#include <sprout/math/factorial.hpp> #include <sprout/math/factorial.hpp>
#include <sprout/math/copysign.hpp> #include <sprout/math/copysign.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -65,17 +64,8 @@ namespace sprout {
return sprout::math::detail::atan(static_cast<double>(x)); return sprout::math::detail::atan(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// atan using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::atan; using sprout::math::atan;

View file

@ -10,8 +10,8 @@
#include <sprout/math/copysign.hpp> #include <sprout/math/copysign.hpp>
#include <sprout/math/signbit.hpp> #include <sprout/math/signbit.hpp>
#include <sprout/math/atan.hpp> #include <sprout/math/atan.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp> #include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -76,20 +76,8 @@ namespace sprout {
return sprout::math::detail::atan2(static_cast<type>(y), static_cast<type>(x)); return sprout::math::detail::atan2(static_cast<type>(y), static_cast<type>(x));
} }
} // namespace detail } // namespace detail
//
// atan2 using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::atan2; using sprout::math::atan2;

View file

@ -10,7 +10,6 @@
#include <sprout/math/log.hpp> #include <sprout/math/log.hpp>
#include <sprout/math/fabs.hpp> #include <sprout/math/fabs.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -47,17 +46,8 @@ namespace sprout {
return sprout::math::detail::atanh(static_cast<double>(x)); return sprout::math::detail::atanh(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// atanh using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::atanh; using sprout::math::atanh;

View file

@ -12,7 +12,6 @@
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/fmod.hpp> #include <sprout/math/fmod.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -61,17 +60,8 @@ namespace sprout {
return sprout::math::detail::cos(static_cast<double>(x)); return sprout::math::detail::cos(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// cos using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::cos; using sprout::math::cos;

View file

@ -10,7 +10,6 @@
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp> #include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -59,17 +58,8 @@ namespace sprout {
return sprout::math::detail::cosh(static_cast<double>(x)); return sprout::math::detail::cosh(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// cosh using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::cosh; using sprout::math::cosh;

View file

@ -102,13 +102,13 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
erf_impl_2_a(T x, T w, T 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> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
erf_impl_1(T x, T w) { erf_impl_1(T x, T w) {
return w < T(2.2) ? sprout::math::detail::erf_impl_2_a(x, w, w * 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)) : 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/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp> #include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -57,17 +56,8 @@ namespace sprout {
return sprout::math::detail::exp(static_cast<double>(x)); return sprout::math::detail::exp(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// exp using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::exp; using sprout::math::exp;

View file

@ -9,7 +9,6 @@
#include <sprout/math/exp.hpp> #include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -41,17 +40,8 @@ namespace sprout {
return sprout::math::detail::exp10(static_cast<double>(x)); return sprout::math::detail::exp10(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// exp10 using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::exp10; using sprout::math::exp10;

View file

@ -9,7 +9,6 @@
#include <sprout/math/exp.hpp> #include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -45,17 +44,8 @@ namespace sprout {
return sprout::math::detail::exp2(static_cast<double>(x)); return sprout::math::detail::exp2(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// exp2 using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::exp2; using sprout::math::exp2;

View file

@ -10,7 +10,6 @@
#include <sprout/math/exp.hpp> #include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::expm1(static_cast<double>(x)); return sprout::math::detail::expm1(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// expm1 using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::expm1; using sprout::math::expm1;

View file

@ -18,7 +18,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
float2_exponent(FloatType x) { float2_exponent(FloatType x) {
return x == 0 ? 0 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 inline SPROUT_CONSTEXPR int
float_exponent(FloatType x) { float_exponent(FloatType x) {
return x == 0 ? 0 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() ? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0) : x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x : 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 inline SPROUT_CONSTEXPR int
fpclassify(FloatType x) { fpclassify(FloatType x) {
return sprout::isnan(x) ? FP_NAN return sprout::math::isnan(x) ? FP_NAN
: sprout::isinf(x) ? FP_INFINITE : sprout::math::isinf(x) ? FP_INFINITE
: sprout::iszero(x) ? FP_ZERO : sprout::math::iszero(x) ? FP_ZERO
: sprout::math::detail::issubnormal_or_zero(x) ? FP_SUBNORMAL : sprout::math::detail::issubnormal_or_zero(x) ? FP_SUBNORMAL
: FP_NORMAL : FP_NORMAL
; ;

View file

@ -21,13 +21,16 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb(FloatType x) { ilogb(FloatType x) {
return sprout::iszero(x) ? FP_ILOGB0 return sprout::math::iszero(x) ? FP_ILOGB0
: sprout::isinf(x) ? INT_MAX : sprout::math::isinf(x) ? INT_MAX
: sprout::isnan(x) ? FP_ILOGBNAN : sprout::math::isnan(x) ? FP_ILOGBNAN
: static_cast<int>(sprout::logb(x)) #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::ilogb(x)
#else
: static_cast<int>(sprout::math::logb(x))
#endif
; ;
} }
template< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
@ -38,7 +41,7 @@ namespace sprout {
} }
} // namespace detail } // namespace detail
using NS_SPROUT_MATH_DETAIL::ilogb; using sprout::math::detail::ilogb;
} // namespace math } // namespace math
using sprout::math::ilogb; using sprout::math::ilogb;

View file

@ -26,16 +26,15 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb2(FloatType x) { ilogb2(FloatType x) {
return sprout::ilogb(x); return sprout::math::ilogb(x);
} }
template< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb2(IntType x) { ilogb2(IntType x) {
return sprout::ilogb(x); return sprout::math::ilogb(x);
} }
#else #else
template< template<
@ -44,13 +43,12 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb2(FloatType x) { ilogb2(FloatType x) {
return sprout::iszero(x) ? FP_ILOGB0 return sprout::math::iszero(x) ? FP_ILOGB0
: sprout::isinf(x) ? INT_MAX : sprout::math::isinf(x) ? INT_MAX
: sprout::isnan(x) ? FP_ILOGBNAN : sprout::math::isnan(x) ? FP_ILOGBNAN
: static_cast<int>(sprout::logb2(x)) : static_cast<int>(sprout::math::logb2(x))
; ;
} }
template< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler 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() 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>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN() : 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 inline SPROUT_CONSTEXPR int
isfinite(FloatType x) { isfinite(FloatType x) {
return !sprout::isnan(x) return !sprout::math::isnan(x)
&& !sprout::isinf(x) && !sprout::math::isinf(x)
; ;
} }
} // namespace detail } // namespace detail

View file

@ -18,8 +18,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
isnormal(FloatType x) { isnormal(FloatType x) {
return !sprout::isnan(x) return !sprout::math::isnan(x)
&& !sprout::isinf(x) && !sprout::math::isinf(x)
&& !sprout::math::detail::issubnormal_or_zero(x) && !sprout::math::detail::issubnormal_or_zero(x)
; ;
} }

View file

@ -28,7 +28,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
issubnormal(FloatType x) { issubnormal(FloatType x) {
return !sprout::iszero(x) return !sprout::math::iszero(x)
&& sprout::math::detail::issubnormal_or_zero(x) && sprout::math::detail::issubnormal_or_zero(x)
; ;
} }

View file

@ -30,7 +30,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR To inline SPROUT_CONSTEXPR To
itrunc(FloatType x) { 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 #else
template< template<

View file

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

View file

@ -138,7 +138,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
lgamma_impl_2_b(T x, T w, T 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> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
@ -165,7 +165,7 @@ namespace sprout {
lgamma_impl_1(T x, T w) { 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) 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(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) : 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/factorial.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -68,17 +67,8 @@ namespace sprout {
return sprout::math::detail::log(static_cast<double>(x)); return sprout::math::detail::log(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// log using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::log; using sprout::math::log;

View file

@ -9,7 +9,6 @@
#include <sprout/math/log.hpp> #include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::log10(static_cast<double>(x)); return sprout::math::detail::log10(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// log10 using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::log10; using sprout::math::log10;

View file

@ -9,7 +9,6 @@
#include <sprout/math/copysign.hpp> #include <sprout/math/copysign.hpp>
#include <sprout/math/log.hpp> #include <sprout/math/log.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::log1p(static_cast<double>(x)); return sprout::math::detail::log1p(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// log1p using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::log1p; using sprout::math::log1p;

View file

@ -9,7 +9,6 @@
#include <sprout/math/log.hpp> #include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::log2(static_cast<double>(x)); return sprout::math::detail::log2(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// log2 using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::log2; using sprout::math::log2;

View file

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

View file

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

View file

@ -1,17 +1,18 @@
#ifndef SPROUT_MATH_LOGB2_HPP #ifndef SPROUT_MATH_LOGB2_HPP
#define SPROUT_MATH_LOGB2_HPP #define SPROUT_MATH_LOGB2_HPP
#include <cstdint>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
#if SPROUT_FLT_RADIX_IS_2 #if SPROUT_FLT_RADIX_IS_2
# include <sprout/math/logb.hpp> # include <sprout/math/logb.hpp>
#else #else
# include <cstdint> # include <cstdint>
# include <limits> # include <limits>
# include <sprout/detail/pow.hpp> # include <sprout/detail/pow.hpp>
# include <sprout/math/detail/float_compute.hpp>
# include <sprout/math/log_a.hpp> # include <sprout/math/log_a.hpp>
# include <sprout/math/trunc.hpp> # include <sprout/math/trunc.hpp>
# include <sprout/math/itrunc.hpp> # include <sprout/math/itrunc.hpp>
@ -27,22 +28,21 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
logb2(FloatType x) { logb2(FloatType x) {
return sprout::logb(x); return sprout::math::logb(x);
} }
template< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR double inline SPROUT_CONSTEXPR double
logb2(IntType x) { logb2(IntType x) {
return sprout::logb(x); return sprout::math::logb(x);
} }
#else #else
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_2_neg_lo(T x, T x0, T base, T exp) { logb2_impl_3_neg_lo(T x, T x0, T base, T exp) {
return base < 1 ? sprout::math::detail::logb2_impl_2_neg_lo( return base < 1 ? sprout::math::detail::logb2_impl_3_neg_lo(
x, x0 * 2, x / (x0 / 2), exp - 1 x, x0 * 2, x / (x0 / 2), exp - 1
) )
: exp : exp
@ -50,8 +50,8 @@ namespace sprout {
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_2_neg_hi(T x, T x0, T base, T exp) { logb2_impl_3_neg_hi(T x, T x0, T base, T exp) {
return !(base < 2) ? sprout::math::detail::logb2_impl_2_neg_hi( return !(base < 2) ? sprout::math::detail::logb2_impl_3_neg_hi(
x, x0 / 2, x / (x0 * 2), exp + 1 x, x0 / 2, x / (x0 * 2), exp + 1
) )
: exp : exp
@ -59,8 +59,8 @@ namespace sprout {
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_2_pos_lo(T x, T x0, T base, T exp) { logb2_impl_3_pos_lo(T x, T x0, T base, T exp) {
return base < 1 ? sprout::math::detail::logb2_impl_2_pos_lo( return base < 1 ? sprout::math::detail::logb2_impl_3_pos_lo(
x, x0 * 2, x / (x0 / 2), exp + 1 x, x0 * 2, x / (x0 / 2), exp + 1
) )
: exp : exp
@ -68,8 +68,8 @@ namespace sprout {
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_2_pos_hi(T x, T x0, T base, T exp) { logb2_impl_3_pos_hi(T x, T x0, T base, T exp) {
return !(base < 2) ? sprout::math::detail::logb2_impl_2_pos_hi( return !(base < 2) ? sprout::math::detail::logb2_impl_3_pos_hi(
x, x0 / 2, x / (x0 * 2), exp - 1 x, x0 / 2, x / (x0 * 2), exp - 1
) )
: exp : exp
@ -77,19 +77,19 @@ namespace sprout {
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_2(T x, T x0, T base, T exp) { logb2_impl_3(T x, T x0, T base, T exp) {
return exp < 0 return x < 1
? base < 1 ? sprout::math::detail::logb2_impl_2_neg_lo( ? base < 1 ? sprout::math::detail::logb2_impl_3_neg_lo(
x, x0 * 2, x / (x0 / 2), exp - 1 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 x, x0 / 2, x / (x0 * 2), exp + 1
) )
: exp : 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 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 x, x0 / 2, x / (x0 * 2), exp - 1
) )
: exp : exp
@ -97,16 +97,23 @@ namespace sprout {
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_1(T x, T x0, T exp) { logb2_impl_2(T x, T x0, T exp) {
return sprout::math::detail::logb2_impl_2(x, x0, x / x0, exp); return sprout::math::detail::logb2_impl_3(x, x0, x / x0, exp);
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl(T x, T exp) { logb2_impl_1(T x, T exp) {
return sprout::math::detail::logb2_impl_1( return sprout::math::detail::logb2_impl_2(
x, sprout::detail::pow_n(T(2), sprout::itrunc<std::intmax_t>(exp)), exp 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< template<
typename FloatType, typename FloatType,
@ -117,11 +124,9 @@ namespace sprout {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? 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))) : static_cast<FloatType>(sprout::math::detail::logb2_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
: sprout::math::detail::logb2_impl(x, sprout::trunc(sprout::log_a(FloatType(2), x)))
; ;
} }
template< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -5,26 +5,33 @@
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/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/detail/pow.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
namespace detail { 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< template<
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
scalbln(FloatType x, long exp) { scalbln(FloatType x, long exp) {
return x == 0 ? FloatType(0) 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>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x : 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< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler

View file

@ -5,26 +5,33 @@
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/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/detail/pow.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
namespace detail { 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< template<
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
scalbn(FloatType x, int exp) { scalbn(FloatType x, int exp) {
return x == 0 ? FloatType(0) 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>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x : 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< template<
typename IntType, typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler 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/copysign.hpp>
#include <sprout/math/cos.hpp> #include <sprout/math/cos.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -47,17 +46,8 @@ namespace sprout {
return sprout::math::detail::sin(static_cast<double>(x)); return sprout::math::detail::sin(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// sin using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::sin; using sprout::math::sin;

View file

@ -11,7 +11,6 @@
#include <sprout/math/copysign.hpp> #include <sprout/math/copysign.hpp>
#include <sprout/math/factorial.hpp> #include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -59,17 +58,8 @@ namespace sprout {
return sprout::math::detail::sinh(static_cast<double>(x)); return sprout::math::detail::sinh(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// sinh using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::sinh; using sprout::math::sinh;

View file

@ -10,7 +10,6 @@
#include <sprout/math/cos.hpp> #include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp> #include <sprout/math/sin.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::tan(static_cast<double>(x)); return sprout::math::detail::tan(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// tan using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::tan; using sprout::math::tan;

View file

@ -10,7 +10,6 @@
#include <sprout/math/sinh.hpp> #include <sprout/math/sinh.hpp>
#include <sprout/math/cosh.hpp> #include <sprout/math/cosh.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout { namespace sprout {
namespace math { namespace math {
@ -46,17 +45,8 @@ namespace sprout {
return sprout::math::detail::tanh(static_cast<double>(x)); return sprout::math::detail::tanh(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
//
// tanh using sprout::math::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);
}
} // namespace math } // namespace math
using sprout::math::tanh; using sprout::math::tanh;