mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-02-04 21:33:56 +00:00
fix math functions
This commit is contained in:
parent
fccb16687b
commit
7794e56192
27 changed files with 342 additions and 102 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/fabs.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
|
@ -15,7 +16,7 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
abs(FloatType x) {
|
||||
return x < 0 ? -x : x;
|
||||
return sprout::math::fabs(x);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ namespace sprout {
|
|||
atan2(FloatType y, FloatType x) {
|
||||
return sprout::math::isnan(y)
|
||||
? sprout::math::isnan(x)
|
||||
? sprout::math::signbit(y) && sprout::math::signbit(x) ? -std::numeric_limits<double>::quiet_NaN()
|
||||
: std::numeric_limits<double>::quiet_NaN()
|
||||
? sprout::math::signbit(y) && sprout::math::signbit(x) ? -std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: y
|
||||
: sprout::math::isnan(x) ? x
|
||||
: x == -std::numeric_limits<FloatType>::infinity()
|
||||
|
|
|
@ -5,24 +5,38 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/pow.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/pow.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
cbrt_impl(T x) {
|
||||
return x < 0 ? -sprout::pow(-x, sprout::math::third<T>())
|
||||
: sprout::pow(x, sprout::math::third<T>())
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
cbrt(FloatType x) {
|
||||
return x == 0 ? FloatType(0)
|
||||
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 < 0 ? -sprout::pow(-x, sprout::math::third<FloatType>())
|
||||
: sprout::pow(x, sprout::math::third<FloatType>())
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::cbrt(x)
|
||||
#else
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::cbrt_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -36,7 +50,7 @@ namespace sprout {
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::cbrt;
|
||||
using sprout::math::detail::cbrt;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::cbrt;
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/itrunc.hpp>
|
||||
#include <sprout/math/fractional_part.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -102,13 +103,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::math::itrunc(t));
|
||||
return sprout::math::detail::erf_impl_2_a_1(x, w, sprout::math::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::math::itrunc(w) - 2)
|
||||
: w < T(6.9) ? sprout::math::detail::erf_impl_2_b(x, w, sprout::math::fractional_part(w), sprout::math::itrunc(w) - 2)
|
||||
: sprout::math::detail::erf_impl_3(x, T(1))
|
||||
;
|
||||
}
|
||||
|
@ -124,14 +125,17 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
erf(FloatType x) {
|
||||
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
|
||||
return x == 0 ? FloatType(0)
|
||||
return sprout::math::isnan(x) ? x
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? FloatType(1)
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
|
||||
: static_cast<FloatType>(sprout::math::detail::erf_impl(static_cast<type>(x)))
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::erf(x)
|
||||
#else
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::erf_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
|
||||
|
@ -142,7 +146,7 @@ namespace sprout {
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::erf;
|
||||
using sprout::math::detail::erf;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::erf;
|
||||
|
|
|
@ -4,24 +4,36 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/erf.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
erfc_impl(T x) {
|
||||
return T(1) - sprout::math::erf(x);
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
erfc(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() ? FloatType(2)
|
||||
: FloatType(1) - sprout::erf(x)
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::erfc(x)
|
||||
#else
|
||||
: static_cast<FloatType>(sprout::math::detail::erfc_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
|
||||
|
@ -32,7 +44,7 @@ namespace sprout {
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::erfc;
|
||||
using sprout::math::detail::erfc;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::erfc;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -16,7 +17,10 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
fabs(FloatType x) {
|
||||
return sprout::math::copysign(x, FloatType(0));
|
||||
return sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? FloatType(0)
|
||||
: sprout::math::copysign(x, FloatType(0))
|
||||
;
|
||||
}
|
||||
template<
|
||||
typename IntType,
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
float2_exponent(FloatType x) {
|
||||
return x == 0 ? 0
|
||||
return sprout::math::isnan(x) ? 0
|
||||
: x == 0 ? 0
|
||||
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? 0
|
||||
: sprout::math::isnan(x) ? FP_ILOGBNAN
|
||||
: sprout::math::ilogb2(x) + 1
|
||||
;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR sprout::pair<FloatType, int>
|
||||
float2_sig_exp(FloatType x) {
|
||||
typedef sprout::pair<FloatType, int> type;
|
||||
return x == std::numeric_limits<FloatType>::infinity() ? type(std::numeric_limits<FloatType>::infinity(), 0)
|
||||
return sprout::math::isnan(x) ? type(x, 0)
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? type(std::numeric_limits<FloatType>::infinity(), 0)
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? type(-std::numeric_limits<FloatType>::infinity(), 0)
|
||||
: sprout::math::isnan(x) ? type(std::numeric_limits<FloatType>::quiet_NaN(), FP_ILOGBNAN)
|
||||
: x == 0 ? type(x, 0)
|
||||
: sprout::math::detail::float2_sig_exp_impl(x, sprout::math::ilogb2(x) + 1)
|
||||
;
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
float2_significand(FloatType x) {
|
||||
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()
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? x
|
||||
: x / sprout::detail::pow_n(FloatType(2), sprout::float2_exponent(x))
|
||||
;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef SPROUT_MATH_FLOAT_EXPONENT_HPP
|
||||
#define SPROUT_MATH_FLOAT_EXPONENT_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
@ -19,9 +18,9 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
float_exponent(FloatType x) {
|
||||
return x == 0 ? 0
|
||||
return sprout::math::isnan(x) ? 0
|
||||
: x == 0 ? 0
|
||||
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? 0
|
||||
: sprout::math::isnan(x) ? FP_ILOGBNAN
|
||||
: sprout::math::ilogb(x) + 1
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef SPROUT_MATH_FLOAT_SIG_EXP_HPP
|
||||
#define SPROUT_MATH_FLOAT_SIG_EXP_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
@ -29,9 +28,9 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR sprout::pair<FloatType, int>
|
||||
float_sig_exp(FloatType x) {
|
||||
typedef sprout::pair<FloatType, int> type;
|
||||
return x == std::numeric_limits<FloatType>::infinity() ? type(std::numeric_limits<FloatType>::infinity(), 0)
|
||||
return sprout::math::isnan(x) ? type(x, 0)
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? type(std::numeric_limits<FloatType>::infinity(), 0)
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? type(-std::numeric_limits<FloatType>::infinity(), 0)
|
||||
: sprout::math::isnan(x) ? type(std::numeric_limits<FloatType>::quiet_NaN(), FP_ILOGBNAN)
|
||||
: x == 0 ? type(x, 0)
|
||||
: sprout::math::detail::float_sig_exp_impl(x, sprout::math::ilogb(x) + 1)
|
||||
;
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
float_significand(FloatType x) {
|
||||
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()
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? x
|
||||
: x / sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), sprout::float_exponent(x))
|
||||
;
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/signbit.hpp>
|
||||
#include <sprout/math/trunc.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/type_traits/float_promote.hpp>
|
||||
|
@ -12,17 +16,32 @@
|
|||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
fmod_impl(T x, T y) {
|
||||
return x - sprout::math::trunc(x / y) * y;
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
fmod(FloatType x, FloatType y) {
|
||||
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() || y == 0
|
||||
? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? FloatType(0)
|
||||
return sprout::math::isnan(y)
|
||||
? sprout::math::isnan(x)
|
||||
? sprout::math::signbit(y) || sprout::math::signbit(x) ? -std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: y
|
||||
: sprout::math::isnan(x) ? x
|
||||
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() || y == 0
|
||||
? -std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? x
|
||||
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x
|
||||
: x - sprout::math::trunc(x / y) * y
|
||||
: static_cast<FloatType>(sprout::math::detail::fmod_impl(
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x),
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(y)
|
||||
))
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR sprout::pair<T, T>
|
||||
frac_int_impl(T x, T ipart) {
|
||||
typedef sprout::pair<T, T> type;
|
||||
return x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity() ? type(sprout::math::copysign(T(0), x), ipart)
|
||||
: sprout::math::isnan(x) ? type(std::numeric_limits<T>::quiet_NaN(), ipart)
|
||||
return sprout::math::isnan(x) ? type(x, ipart)
|
||||
: x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity() ? type(sprout::math::copysign(T(0), x), ipart)
|
||||
: x == 0 ? type(x, ipart)
|
||||
: x == ipart ? type(T(0) * x, ipart)
|
||||
: type(sprout::math::copysign(x - ipart, x), ipart)
|
||||
|
|
|
@ -27,8 +27,8 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
fractional_part(FloatType x) {
|
||||
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? sprout::math::copysign(FloatType(0), x)
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
return sprout::math::isnan(x) ? x
|
||||
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: sprout::math::detail::fractional_part_impl(x, sprout::integer_part(x))
|
||||
;
|
||||
|
|
|
@ -7,5 +7,6 @@
|
|||
#include <sprout/math/factorial.hpp>
|
||||
#include <sprout/math/bernoulli.hpp>
|
||||
#include <sprout/math/comparison.hpp>
|
||||
#include <sprout/math/integer.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_FUNCTIONS_HPP
|
||||
|
|
|
@ -4,28 +4,59 @@
|
|||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/float_promote.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/signbit.hpp>
|
||||
#include <sprout/math/fabs.hpp>
|
||||
#include <sprout/math/sqrt.hpp>
|
||||
#include <sprout/type_traits/float_promote.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
hypot_impl_2(T t, T w) {
|
||||
return t * sprout::math::sqrt(T(1) + w * w);
|
||||
}
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
hypot_impl_1(T x, T y) {
|
||||
return x < y
|
||||
? sprout::math::detail::hypot_impl_2(y, x / y)
|
||||
: sprout::math::detail::hypot_impl_2(x, y / x)
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
hypot_impl(T x, T y) {
|
||||
return sprout::math::detail::hypot_impl_1(sprout::math::fabs(x), sprout::math::fabs(y));
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
hypot(FloatType x, FloatType y) {
|
||||
return y == 0 ? sprout::math::fabs(x)
|
||||
: x == 0 ? sprout::math::fabs(y)
|
||||
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()
|
||||
return y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()
|
||||
? std::numeric_limits<FloatType>::infinity()
|
||||
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
|
||||
? std::numeric_limits<FloatType>::infinity()
|
||||
: sprout::math::sqrt(x * x + y * y)
|
||||
: sprout::math::isnan(y) ? y
|
||||
: sprout::math::isnan(x) ? x
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::hypot(x, y)
|
||||
#else
|
||||
: y == 0 ? sprout::math::fabs(x)
|
||||
: x == 0 ? sprout::math::fabs(y)
|
||||
: static_cast<FloatType>(sprout::math::detail::hypot_impl(
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x),
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(y)
|
||||
))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -43,7 +74,7 @@ namespace sprout {
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::hypot;
|
||||
using sprout::math::detail::hypot;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::hypot;
|
||||
|
|
9
sprout/math/integer.hpp
Normal file
9
sprout/math/integer.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef SPROUT_MATH_INTEGER_HPP
|
||||
#define SPROUT_MATH_INTEGER_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/is_integer.hpp>
|
||||
#include <sprout/math/is_odd.hpp>
|
||||
#include <sprout/math/is_even.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_INTEGER_HPP
|
|
@ -18,9 +18,9 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
integer_part(FloatType x) {
|
||||
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()
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? x
|
||||
: sprout::math::trunc(x)
|
||||
;
|
||||
|
|
28
sprout/math/is_even.hpp
Normal file
28
sprout/math/is_even.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef SPROUT_MATH_IS_EVEN_HPP
|
||||
#define SPROUT_MATH_IS_EVEN_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/math/fmod.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_even(FloatType x) {
|
||||
return sprout::math::fmod(x, FloatType(2)) == FloatType(0);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
using sprout::math::detail::is_even;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::is_even;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_IS_EVEN_HPP
|
28
sprout/math/is_integer.hpp
Normal file
28
sprout/math/is_integer.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef SPROUT_MATH_IS_INTEGER_HPP
|
||||
#define SPROUT_MATH_IS_INTEGER_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/math/trunc.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_integer(FloatType x) {
|
||||
return x == sprout::math::trunc(x);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
using sprout::math::detail::is_integer;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::is_integer;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_IS_INTEGER_HPP
|
28
sprout/math/is_odd.hpp
Normal file
28
sprout/math/is_odd.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef SPROUT_MATH_IS_ODD_HPP
|
||||
#define SPROUT_MATH_IS_ODD_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/math/fmod.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_odd(FloatType x) {
|
||||
return sprout::math::fmod(x, FloatType(2)) == FloatType(1);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
using sprout::math::detail::is_odd;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::is_odd;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_IS_ODD_HPP
|
|
@ -7,11 +7,13 @@
|
|||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/factorial.hpp>
|
||||
#include <sprout/math/log.hpp>
|
||||
#include <sprout/math/sin.hpp>
|
||||
#include <sprout/math/fabs.hpp>
|
||||
#include <sprout/math/itrunc.hpp>
|
||||
#include <sprout/math/is_integer.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -181,13 +183,17 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
lgamma(FloatType x) {
|
||||
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
|
||||
return x == 1 ? FloatType(0)
|
||||
: x == 2 ? FloatType(0)
|
||||
: x <= 0 && x == std::trunc(x) ? std::numeric_limits<FloatType>::infinity()
|
||||
return sprout::math::isnan(x) ? x
|
||||
: x <= 0 && sprout::math::is_integer(x) ? 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()
|
||||
: static_cast<FloatType>(sprout::math::detail::lgamma_impl(static_cast<type>(x)))
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::lgamma(x)
|
||||
#else
|
||||
: x == 1 ? FloatType(0)
|
||||
: x == 2 ? FloatType(0)
|
||||
: static_cast<FloatType>(sprout::math::detail::lgamma_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -201,7 +207,7 @@ namespace sprout {
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::lgamma;
|
||||
using sprout::math::detail::lgamma;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::lgamma;
|
||||
|
|
|
@ -4,24 +4,34 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/log.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/log.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
|
||||
log_a_impl(T x, T y) {
|
||||
return x == 2 ? sprout::math::log(y) / sprout::math::ln_two<T>()
|
||||
: x == 10 ? sprout::math::log(y) / sprout::math::ln_ten<T>()
|
||||
: sprout::math::log(y) / sprout::math::log(x)
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
log_a(FloatType x, FloatType y) {
|
||||
return x == 2 ? sprout::math::log(y) / sprout::math::ln_two<FloatType>()
|
||||
: x == 10 ? sprout::math::log(y) / sprout::math::ln_ten<FloatType>()
|
||||
: sprout::math::log(y) / sprout::math::log(x)
|
||||
;
|
||||
return static_cast<FloatType>(sprout::math::detail::log_a_impl(
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x),
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(y)
|
||||
));
|
||||
}
|
||||
|
||||
template<
|
||||
|
|
|
@ -5,45 +5,67 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/fabs.hpp>
|
||||
#include <sprout/math/exp.hpp>
|
||||
#include <sprout/math/log.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/is_integer.hpp>
|
||||
#include <sprout/math/is_odd.hpp>
|
||||
#include <sprout/type_traits/float_promote.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
pow_impl(T x, T y) {
|
||||
return sprout::math::exp(y * sprout::math::log(x));
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
pow(FloatType x, FloatType y) {
|
||||
return x == 0
|
||||
? y < 0 ? std::numeric_limits<FloatType>::infinity()
|
||||
: y > 0 ? FloatType(0)
|
||||
: sprout::math::exp(y * sprout::math::log(x))
|
||||
: x == -1 && (y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()) ? FloatType(1)
|
||||
: x == 1 ? FloatType(1)
|
||||
return x == 1 ? FloatType(1)
|
||||
: y == 0 ? FloatType(1)
|
||||
: sprout::math::isnan(y) ? y
|
||||
: sprout::math::isnan(x) ? x
|
||||
: x == 0
|
||||
? y < 0
|
||||
? sprout::math::is_odd(y) ? sprout::math::copysign(std::numeric_limits<FloatType>::infinity(), x)
|
||||
: std::numeric_limits<FloatType>::infinity()
|
||||
: sprout::math::is_odd(y) ? x
|
||||
: FloatType(0)
|
||||
: x == -1 && (y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()) ? FloatType(1)
|
||||
: y == -std::numeric_limits<FloatType>::infinity()
|
||||
? x < 1 && x > -1 ? std::numeric_limits<FloatType>::infinity()
|
||||
: x > 1 || x < -1 ? FloatType(0)
|
||||
: sprout::math::exp(y * sprout::math::log(x))
|
||||
? sprout::math::fabs(x) < 1 ? std::numeric_limits<FloatType>::infinity()
|
||||
: FloatType(0)
|
||||
: y == std::numeric_limits<FloatType>::infinity()
|
||||
? x < 1 && x > -1 ? FloatType(0)
|
||||
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::infinity()
|
||||
: sprout::math::exp(y * sprout::math::log(x))
|
||||
? sprout::math::fabs(x) < 1 ? FloatType(0)
|
||||
: std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity()
|
||||
? y < 0 ? FloatType(0)
|
||||
: y > 0 ? std::numeric_limits<FloatType>::infinity()
|
||||
: sprout::math::exp(y * sprout::math::log(x))
|
||||
? y < 0
|
||||
? sprout::math::is_odd(y) ? -FloatType(0)
|
||||
: FloatType(0)
|
||||
: sprout::math::is_odd(y) ? -std::numeric_limits<FloatType>::infinity()
|
||||
: std::numeric_limits<FloatType>::infinity()
|
||||
: x == std::numeric_limits<FloatType>::infinity()
|
||||
? y < 0 ? FloatType(0)
|
||||
: y > 0 ? std::numeric_limits<FloatType>::infinity()
|
||||
: sprout::math::exp(y * sprout::math::log(x))
|
||||
: sprout::math::exp(y * sprout::math::log(x))
|
||||
: std::numeric_limits<FloatType>::infinity()
|
||||
: x < 0 && !sprout::math::is_integer(y) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::pow(x, y)
|
||||
#else
|
||||
: static_cast<FloatType>(sprout::math::detail::pow_impl(
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x),
|
||||
static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(y)
|
||||
))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -60,8 +82,13 @@ namespace sprout {
|
|||
return sprout::math::detail::pow(static_cast<type>(x), static_cast<type>(y));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::pow;
|
||||
//
|
||||
// issue:
|
||||
// [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
|
||||
// pow(-0, y) returns -<2D>‡ for y an odd integer < 0.
|
||||
// # returns +<2B>‡ . ( same as pow(+0, y) )
|
||||
//
|
||||
using sprout::math::detail::pow;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::pow;
|
||||
|
|
|
@ -14,15 +14,20 @@ namespace sprout {
|
|||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
sqrt_impl_1(T x, T s, T s2) {
|
||||
sqrt_impl_2(T x, T s, T s2) {
|
||||
return !(s < s2) ? s2
|
||||
: sprout::math::detail::sqrt_impl_1(x, (x / s + s) / 2, s)
|
||||
: sprout::math::detail::sqrt_impl_2(x, (x / s + s) / 2, s)
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
sqrt_impl(T x, T s) {
|
||||
return sprout::math::detail::sqrt_impl_1(x, (x / s + s) / 2, s);
|
||||
sqrt_impl_1(T x, T s) {
|
||||
return sprout::math::detail::sqrt_impl_2(x, (x / s + s) / 2, s);
|
||||
}
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
sqrt_impl(T x) {
|
||||
return sprout::math::detail::sqrt_impl_1(x, x > 1 ? x : T(1));
|
||||
}
|
||||
|
||||
template<
|
||||
|
@ -31,12 +36,16 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
sqrt(FloatType x) {
|
||||
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
|
||||
return x == 0 ? FloatType(0)
|
||||
return sprout::math::isnan(x) ? x
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: static_cast<FloatType>(sprout::math::detail::sqrt_impl(static_cast<type>(x), x > 1 ? static_cast<type>(x) : type(1)));
|
||||
: x < 0 ? -std::numeric_limits<FloatType>::quiet_NaN()
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::sqrt(x)
|
||||
#else
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::sqrt_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
template<
|
||||
typename IntType,
|
||||
|
@ -48,7 +57,7 @@ namespace sprout {
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::sqrt;
|
||||
using sprout::math::detail::sqrt;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::sqrt;
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/factorial.hpp>
|
||||
#include <sprout/math/iround.hpp>
|
||||
#include <sprout/math/trunc.hpp>
|
||||
#include <sprout/math/is_integer.hpp>
|
||||
#include <sprout/algorithm/clamp.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include HDR_ALGORITHM_MIN_MAX_SSCRISK_CEL_OR_SPROUT
|
||||
|
@ -105,12 +107,16 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
tgamma(FloatType x) {
|
||||
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
|
||||
return x == 0 ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
return sprout::math::isnan(x) ? x
|
||||
: x == 0 ? sprout::math::copysign(std::numeric_limits<FloatType>::infinity(), x)
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x < 0 && x == std::trunc(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: static_cast<FloatType>(sprout::math::detail::tgamma_impl(static_cast<type>(x)))
|
||||
: x < 0 && sprout::math::is_integer(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::tgamma(x)
|
||||
#else
|
||||
: static_cast<FloatType>(sprout::math::detail::tgamma_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -123,8 +129,13 @@ namespace sprout {
|
|||
return sprout::math::detail::tgamma(static_cast<double>(x));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
using NS_SPROUT_MATH_DETAIL::tgamma;
|
||||
//
|
||||
// issue:
|
||||
// [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
|
||||
// tgamma(-0) returns -<2D>‡ .
|
||||
// # returns +<2B>‡ . ( same as tgamma(+0) )
|
||||
//
|
||||
using sprout::math::detail::tgamma;
|
||||
} // namespace math
|
||||
|
||||
using sprout::math::tgamma;
|
||||
|
|
Loading…
Add table
Reference in a new issue