fix math functions

This commit is contained in:
bolero-MURAKAMI 2013-05-05 00:06:30 +09:00
parent ffb876c930
commit fccb16687b
20 changed files with 209 additions and 68 deletions

View file

@ -9,7 +9,6 @@
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/isnan.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/math/fabs.hpp> #include <sprout/math/fabs.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
@ -20,21 +19,54 @@ namespace sprout {
namespace detail { namespace detail {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
asin_impl_1(T x, std::size_t n, std::size_t last) { asin_impl_center_1(T x, T x2) {
return last - n == 1 return ((((((((((((
? sprout::math::unchecked_factorial<T>(2 * n) + 0.0316658385792867081040808) * x2
/ sprout::detail::pow_n(T(4), n) / sprout::detail::pow2(sprout::math::unchecked_factorial<T>(n)) / (2 * n + 1) + -0.0158620440988475212803145) * x2
* sprout::detail::pow_n(x, 2 * n + 1) + 0.0192942786775238654913582) * x2
: sprout::math::detail::asin_impl_1(x, n, n + (last - n) / 2) + 0.0066153165197009078340075) * x2
+ sprout::math::detail::asin_impl_1(x, n + (last - n) / 2, last) + 0.0121483892822292648695383) * x2
+ 0.0138885410156894774969889) * x2
+ 0.0173593516996479249428647) * x2
+ 0.0223717830666671020710108) * x2
+ 0.0303819580081956423799529) * x2
+ 0.0446428568582815922683933) * x2
+ 0.0750000000029696112392353) * x2
+ 0.1666666666666558995379880) * x2
* x + x
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
asin_impl_center(T x) {
return sprout::math::detail::asin_impl_center_1(x, x * x);
}
template<typename T>
inline SPROUT_CONSTEXPR T
asin_impl_tail(T x) {
return sprout::math::half_pi<T>() + sprout::math::sqrt(T(1) - x)
* (((((((((((((
+ -0.0000121189820098929624806) * x
+ 0.0001307564187657962919394) * x
+ -0.0006702485124770180942917) * x
+ 0.0021912255981979442677477) * x
+ -0.0052049731575223952626203) * x
+ 0.0097868293573384001221447) * x
+ -0.0156746038587246716524035) * x
+ 0.0229883479552557203133368) * x
+ -0.0331919619444009606270380) * x
+ 0.0506659694457588602631748) * x
+ -0.0890259194305537131666744) * x
+ 0.2145993335526539017488949) * x
+ -1.5707961988153774692344105)
; ;
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
asin_impl(T x) { asin_impl(T x) {
return x > sprout::math::half_root_two<T>() return x < T(-0.5) ? -sprout::math::detail::asin_impl_tail(-x)
? sprout::math::half_pi<T>() - sprout::math::detail::asin_impl_1(sprout::math::sqrt(1 - x * x), 0, sprout::math::factorial_limit<T>() / 2 + 1) : x > T(0.5) ? sprout::math::detail::asin_impl_tail(x)
: x + sprout::math::detail::asin_impl_1(x, 1, sprout::math::factorial_limit<T>() / 2 + 1) : sprout::math::detail::asin_impl_center(x)
; ;
} }

View file

@ -8,8 +8,11 @@
#include <sprout/detail/pow.hpp> #include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
//#include <sprout/math/detail/cosp.hpp>
//#include <sprout/math/detail/sinp.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/math/factorial.hpp> #include <sprout/math/factorial.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>
@ -35,6 +38,31 @@ namespace sprout {
); );
} }
// template<typename T>
// inline SPROUT_CONSTEXPR T
// cos_impl_2(T x) {
// return x <= sprout::math::quarter_pi<T>() ? -sprout::math::detail::cosp(x)
// : x <= sprout::math::half_pi<T>() ? -sprout::math::detail::sinp(sprout::math::half_pi<T>() - x)
// : x <= sprout::math::three_quarters_pi<T>() ? sprout::math::detail::sinp(x - sprout::math::half_pi<T>())
// : sprout::math::detail::cosp(sprout::math::pi<T>() - x)
// ;
// }
// template<typename T>
// inline SPROUT_CONSTEXPR T
// cos_impl_1(T x) {
// return x > sprout::math::pi<T>() ? sprout::math::detail::cos_impl_2(x - sprout::math::pi<T>())
// : x <= sprout::math::quarter_pi<T>() ? sprout::math::detail::cosp(x)
// : x <= sprout::math::half_pi<T>() ? sprout::math::detail::sinp(sprout::math::half_pi<T>() - x)
// : x <= sprout::math::three_quarters_pi<T>() ? -sprout::math::detail::sinp(x - sprout::math::half_pi<T>())
// : -sprout::math::detail::cosp(sprout::math::pi<T>() - x)
// ;
// }
// template<typename T>
// inline SPROUT_CONSTEXPR T
// cos_impl(T x) {
// return sprout::math::detail::cos_impl_1(sprout::math::fmod(sprout::math::fabs(x), sprout::math::two_pi<T>()));
// }
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

View file

@ -5,11 +5,10 @@
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/isnan.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/math/factorial.hpp> #include <sprout/math/exp.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -17,20 +16,13 @@ namespace sprout {
namespace detail { namespace detail {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
cosh_impl_1(T x2, std::size_t n, std::size_t last) { cosh_impl_1(T t) {
return last - n == 1 return T(0.5) * t + T(0.5) / t;
? sprout::detail::pow_n(x2, n) / sprout::math::unchecked_factorial<T>(2 * n)
: sprout::math::detail::cosh_impl_1(x2, n, n + (last - n) / 2)
+ sprout::math::detail::cosh_impl_1(x2, n + (last - n) / 2, last)
;
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
cosh_impl(T x) { cosh_impl(T x) {
return T(1) + sprout::math::detail::cosh_impl_1( return sprout::math::detail::cosh_impl_1(sprout::math::exp(x));
x * x,
1, sprout::math::factorial_limit<T>() / 2 + 1
);
} }
template< template<

View file

@ -0,0 +1,32 @@
#ifndef SPROUT_MATH_DETAIL_COSP_HPP
#define SPROUT_MATH_DETAIL_COSP_HPP
#include <sprout/config.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
cosp_impl(T x2) {
return (((((((
-1.13585365213876817300e-11) * x2
+ 2.08757008419747316778e-9) * x2
- 2.75573141792967388112e-7) * x2
+ 2.48015872888517045348e-5) * x2
- 1.38888888888730564116e-3) * x2
+ 4.16666666666665929218e-2) * x2
- 0.5) * x2
+ 1.0
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
cosp(T x) {
return sprout::math::detail::cosp_impl(x * x);
}
} // namespace detail
} // namespace math
} // namespace sprout
#endif // #ifndef SPROUT_MATH_DETAIL_COSP_HPP

View file

@ -0,0 +1,30 @@
#ifndef SPROUT_MATH_DETAIL_SINP_HPP
#define SPROUT_MATH_DETAIL_SINP_HPP
#include <sprout/config.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
sinp_impl(T x, T x2) {
return x + x * (((((((
1.58962301576546568060e-10) * x2
- 2.50507477628578072866e-8) * x2
+ 2.75573136213857245213e-6) * x2
- 1.98412698295895385996e-4) * x2
+ 8.33333333332211858878e-3) * x2
- 1.66666666666666307295e-1) * x2
);
}
template<typename T>
inline SPROUT_CONSTEXPR T
sinp(T x) {
return sprout::math::detail::sinp_impl(x, x * x);
}
} // namespace detail
} // namespace math
} // namespace sprout
#endif // #ifndef SPROUT_MATH_DETAIL_SINP_HPP

View file

@ -8,6 +8,7 @@
#include <sprout/detail/pow.hpp> #include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/isnan.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>
@ -37,7 +38,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
exp(FloatType x) { exp(FloatType x) {
return x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) return sprout::math::isnan(x) ? x
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::exp(x) : std::exp(x)

View file

@ -6,8 +6,9 @@
#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/detail/float_compute.hpp>
#include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/exp.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
exp10(FloatType x) { exp10(FloatType x) {
return x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) return sprout::math::isnan(x) ? x
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == 0 ? FloatType(1) : x == 0 ? FloatType(1)
: static_cast<FloatType>(sprout::math::detail::exp10_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x))) : static_cast<FloatType>(sprout::math::detail::exp10_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))

View file

@ -6,8 +6,9 @@
#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/detail/float_compute.hpp>
#include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/exp.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
exp2(FloatType x) { exp2(FloatType x) {
return x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) return sprout::math::isnan(x) ? x
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::exp2(x) : std::exp2(x)

View file

@ -6,9 +6,10 @@
#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/detail/float_compute.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/copysign.hpp> #include <sprout/math/copysign.hpp>
#include <sprout/math/exp.hpp> #include <sprout/math/exp.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -26,7 +27,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
expm1(FloatType x) { expm1(FloatType x) {
return x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1) return sprout::math::isnan(x) ? x
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::expm1(x) : std::expm1(x)

View file

@ -4,9 +4,10 @@
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/detail/pow.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -24,7 +25,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
ldexp(FloatType x, int exp) { ldexp(FloatType x, int exp) {
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: 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 == 0 ? x : x == 0 ? x

View file

@ -9,6 +9,7 @@
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#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>
@ -47,7 +48,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
log(FloatType x) { log(FloatType x) {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: x == 0 ? -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 < 0 ? std::numeric_limits<FloatType>::quiet_NaN() : x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION

View file

@ -6,8 +6,9 @@
#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/detail/float_compute.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/log.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
log10(FloatType x) { log10(FloatType x) {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: x == 0 ? -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 < 0 ? std::numeric_limits<FloatType>::quiet_NaN() : x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION

View file

@ -6,6 +6,7 @@
#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/detail/float_compute.hpp>
#include <sprout/math/isnan.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>
@ -24,9 +25,10 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
log1p(FloatType x) { log1p(FloatType x) {
return x == -1 ? -std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: x == -1 ? -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 < -1 ? std::numeric_limits<FloatType>::quiet_NaN() : x < -1 ? -std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::log1p(x) : std::log1p(x)
#else #else

View file

@ -6,8 +6,9 @@
#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/detail/float_compute.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/log.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
log2(FloatType x) { log2(FloatType x) {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: x == 0 ? -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 < 0 ? std::numeric_limits<FloatType>::quiet_NaN() : x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION

View file

@ -8,6 +8,7 @@
#include <sprout/detail/pow.hpp> #include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/isnan.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>
@ -39,7 +40,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb_impl_3_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_3_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
; ;
@ -48,7 +49,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb_impl_3_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_3_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
; ;
@ -65,10 +66,10 @@ namespace sprout {
) )
: exp : exp
: base < 1 ? sprout::math::detail::logb_impl_3_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_3_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
; ;
@ -99,7 +100,8 @@ 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 sprout::math::isnan(x) ? x
: x == 0 ? -std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
# if defined(__GNUC__) # if defined(__GNUC__)
: x == -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity()

View file

@ -13,6 +13,7 @@
# include <limits> # include <limits>
# include <sprout/detail/pow.hpp> # include <sprout/detail/pow.hpp>
# include <sprout/math/detail/float_compute.hpp> # include <sprout/math/detail/float_compute.hpp>
# include <sprout/math/isnan.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>
@ -61,7 +62,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_3_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_3_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
; ;
@ -70,7 +71,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl_3_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_3_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
; ;
@ -87,10 +88,10 @@ namespace sprout {
) )
: exp : exp
: base < 1 ? sprout::math::detail::logb2_impl_3_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_3_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
; ;
@ -121,7 +122,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
logb2(FloatType x) { logb2(FloatType x) {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: 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()
: static_cast<FloatType>(sprout::math::detail::logb2_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x))) : static_cast<FloatType>(sprout::math::detail::logb2_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))

View file

@ -4,9 +4,10 @@
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/detail/pow.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -24,7 +25,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
scalbln(FloatType x, long exp) { scalbln(FloatType x, long exp) {
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: 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 == 0 ? x : x == 0 ? x

View file

@ -4,9 +4,10 @@
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/detail/pow.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -24,7 +25,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
scalbn(FloatType x, int exp) { scalbn(FloatType x, int exp) {
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
: 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 == 0 ? x : x == 0 ? x

View file

@ -5,11 +5,10 @@
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/isnan.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/math/factorial.hpp> #include <sprout/math/exp.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -17,20 +16,13 @@ namespace sprout {
namespace detail { namespace detail {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
sinh_impl_1(T x, std::size_t n, std::size_t last) { sinh_impl_1(T t) {
return last - n == 1 return T(0.5) * t - T(0.5) / t;
? sprout::detail::pow_n(x, 2 * n + 1) / sprout::math::unchecked_factorial<T>(2 * n + 1)
: sprout::math::detail::sinh_impl_1(x, n, n + (last - n) / 2)
+ sprout::math::detail::sinh_impl_1(x, n + (last - n) / 2, last)
;
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
sinh_impl(T x) { sinh_impl(T x) {
return x + sprout::math::detail::sinh_impl_1( return sprout::math::detail::sinh_impl_1(sprout::math::exp(x));
x,
1, (sprout::math::factorial_limit<T>() - 1) / 2 + 1
);
} }
template< template<

View file

@ -7,17 +7,26 @@
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp> #include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/isnan.hpp> #include <sprout/math/isnan.hpp>
#include <sprout/math/sinh.hpp> #include <sprout/math/exp.hpp>
#include <sprout/math/cosh.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
tanh_impl_2(T t, T u) {
return (t - u) / (t + u);
}
template<typename T>
inline SPROUT_CONSTEXPR T
tanh_impl_1(T t) {
return sprout::math::detail::tanh_impl_2(t, T(1) / t);
}
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
tanh_impl(T x) { tanh_impl(T x) {
return sprout::math::sinh(x) / sprout::math::cosh(x); return sprout::math::detail::tanh_impl_1(sprout::math::exp(x));
} }
template< template<