mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
fix math functions
This commit is contained in:
parent
dad3acceea
commit
2e2b6c96ab
30 changed files with 121 additions and 84 deletions
|
@ -10,7 +10,6 @@
|
|||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/factorial.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/fabs.hpp>
|
||||
#include <sprout/math/sqrt.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
@ -48,7 +47,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::asin(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(
|
||||
x < 0 ? -sprout::math::detail::asin_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(-x))
|
||||
: sprout::math::detail::asin_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x))
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/log.hpp>
|
||||
#include <sprout/math/sqrt.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
@ -31,7 +30,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::asinh(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::asinh_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/factorial.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -47,7 +46,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::atan(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(
|
||||
x < 0 ? -sprout::math::detail::atan_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(-x))
|
||||
: sprout::math::detail::atan_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x))
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace sprout {
|
|||
: x == std::numeric_limits<FloatType>::infinity()
|
||||
? y == std::numeric_limits<FloatType>::infinity() ? sprout::math::quarter_pi<FloatType>()
|
||||
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::quarter_pi<FloatType>()
|
||||
: sprout::math::copysign(FloatType(0), y)
|
||||
: FloatType(0) * y
|
||||
: y == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>()
|
||||
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>()
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
|
@ -48,9 +48,9 @@ namespace sprout {
|
|||
#else
|
||||
: y == 0
|
||||
? x < 0 ? sprout::math::copysign(sprout::math::pi<FloatType>(), y)
|
||||
: x > 0 ? sprout::math::copysign(FloatType(0), y)
|
||||
: x > 0 ? FloatType(0) * y
|
||||
: sprout::math::signbit(x) ? sprout::math::copysign(sprout::math::pi<FloatType>(), y)
|
||||
: sprout::math::copysign(FloatType(0), y)
|
||||
: FloatType(0) * y
|
||||
: x == 0
|
||||
? y < 0 ? -sprout::math::half_pi<FloatType>()
|
||||
: sprout::math::half_pi<FloatType>()
|
||||
|
@ -76,7 +76,13 @@ namespace sprout {
|
|||
return sprout::math::detail::atan2(static_cast<type>(y), static_cast<type>(x));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// bug:
|
||||
// atan2(<28>}0, -0) returns <20>}ƒÎ .
|
||||
// # returns <20>}0 . ( same as atan2(<28>}0, +0) )
|
||||
// atan2(-0, x) returns -ƒÎ for x < 0.
|
||||
// # returns +ƒÎ . ( same as atan2(+0, x) )
|
||||
//
|
||||
using sprout::math::detail::atan2;
|
||||
} // namespace math
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/log.hpp>
|
||||
#include <sprout/math/fabs.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
@ -32,7 +31,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::atanh(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::atanh_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -17,7 +17,11 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
copysign(FloatType x, FloatType y) {
|
||||
return sprout::math::signbit(y) != sprout::math::signbit(x) ? -x
|
||||
return x == 0
|
||||
? y == 0 ? y
|
||||
: sprout::math::signbit(y) ? -FloatType(0)
|
||||
: FloatType(0)
|
||||
: sprout::math::signbit(y) != sprout::math::signbit(x) ? -x
|
||||
: x
|
||||
;
|
||||
}
|
||||
|
@ -34,7 +38,11 @@ namespace sprout {
|
|||
return sprout::math::detail::copysign(static_cast<type>(x), static_cast<type>(y));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// bug:
|
||||
// copysign(<28>}x, -0) returns -x for |x| > 0 .
|
||||
// # returns +x . ( same as copysign(<28>}x, +0) )
|
||||
//
|
||||
using NS_SPROUT_MATH_DETAIL::copysign;
|
||||
} // namespace math
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::expm1(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::expm1_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#ifndef SPROUT_MATH_FLOAT2_EXPONENT_HPP
|
||||
#define SPROUT_MATH_FLOAT2_EXPONENT_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/ilogb2.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -18,10 +20,11 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR int
|
||||
float2_exponent(FloatType x) {
|
||||
return 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
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#ifndef SPROUT_MATH_FLOAT2_SIG_EXP_HPP
|
||||
#define SPROUT_MATH_FLOAT2_SIG_EXP_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/math/float2_exponent.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/ilogb2.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/utility/pair/pair.hpp>
|
||||
|
||||
|
@ -17,12 +19,7 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR sprout::pair<T, int>
|
||||
float2_sig_exp_impl(T x, int exp) {
|
||||
typedef sprout::pair<T, int> type;
|
||||
return x == 0 ? type(T(0), exp)
|
||||
: x == std::numeric_limits<T>::infinity() ? type(std::numeric_limits<T>::infinity(), exp)
|
||||
: x == -std::numeric_limits<T>::infinity() ? type(-std::numeric_limits<T>::infinity(), exp)
|
||||
: x == std::numeric_limits<T>::quiet_NaN() ? type(std::numeric_limits<T>::quiet_NaN(), exp)
|
||||
: type(x / sprout::detail::pow_n(T(2), exp), exp)
|
||||
;
|
||||
return type(x / sprout::detail::pow_n(T(2), exp), exp);
|
||||
}
|
||||
|
||||
template<
|
||||
|
@ -31,9 +28,14 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<FloatType, int>
|
||||
float2_sig_exp(FloatType x) {
|
||||
return sprout::math::detail::float2_sig_exp_impl(x, sprout::math::float2_exponent(x));
|
||||
typedef sprout::pair<FloatType, int> type;
|
||||
return 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)
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/float2_exponent.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -18,14 +19,13 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
float2_significand(FloatType x) {
|
||||
return x == 0 ? FloatType(0)
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
|
||||
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? x
|
||||
: x / sprout::detail::pow_n(FloatType(2), sprout::float2_exponent(x))
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#ifndef SPROUT_MATH_FLOAT_EXPONENT_HPP
|
||||
#define SPROUT_MATH_FLOAT_EXPONENT_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/ilogb.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -18,10 +20,11 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR int
|
||||
float_exponent(FloatType x) {
|
||||
return 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
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#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>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/math/float_exponent.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/ilogb.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/utility/pair/pair.hpp>
|
||||
|
||||
|
@ -17,12 +19,7 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR sprout::pair<T, int>
|
||||
float_sig_exp_impl(T x, int exp) {
|
||||
typedef sprout::pair<T, int> type;
|
||||
return x == 0 ? type(T(0), exp)
|
||||
: x == std::numeric_limits<T>::infinity() ? type(std::numeric_limits<T>::infinity(), exp)
|
||||
: x == -std::numeric_limits<T>::infinity() ? type(-std::numeric_limits<T>::infinity(), exp)
|
||||
: x == std::numeric_limits<T>::quiet_NaN() ? type(std::numeric_limits<T>::quiet_NaN(), exp)
|
||||
: type(x / sprout::detail::pow_n(T(std::numeric_limits<T>::radix), exp), exp)
|
||||
;
|
||||
return type(x / sprout::detail::pow_n(T(std::numeric_limits<T>::radix), exp), exp);
|
||||
}
|
||||
|
||||
template<
|
||||
|
@ -31,9 +28,14 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<FloatType, int>
|
||||
float_sig_exp(FloatType x) {
|
||||
return sprout::math::detail::float_sig_exp_impl(x, sprout::float_exponent(x));
|
||||
typedef sprout::pair<FloatType, int> type;
|
||||
return 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)
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/float_exponent.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -18,14 +19,13 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
float_significand(FloatType x) {
|
||||
return x == 0 ? FloatType(0)
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
|
||||
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: 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))
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef SPROUT_MATH_FMAX_HPP
|
||||
#define SPROUT_MATH_FMAX_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/type_traits/float_promote.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -17,9 +17,8 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
fmax(FloatType x, FloatType y) {
|
||||
return x < y && !y == std::numeric_limits<FloatType>::quiet_NaN() ? y : x;
|
||||
return x < y && !sprout::math::isnan(y) ? y : x;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ArithmeticType1,
|
||||
typename ArithmeticType2,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef SPROUT_MATH_FMIN_HPP
|
||||
#define SPROUT_MATH_FMIN_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/type_traits/float_promote.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -17,9 +17,8 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
fmin(FloatType x, FloatType y) {
|
||||
return x > y && !y == std::numeric_limits<FloatType>::quiet_NaN() ? y : x;
|
||||
return y < x && !sprout::math::isnan(y) ? y : x;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ArithmeticType1,
|
||||
typename ArithmeticType2,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/integer_part.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/utility/pair/pair.hpp>
|
||||
|
@ -16,9 +18,11 @@ 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(T(0), ipart)
|
||||
: x == std::numeric_limits<T>::quiet_NaN() ? type(std::numeric_limits<T>::quiet_NaN(), ipart)
|
||||
: type(x - ipart, ipart)
|
||||
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)
|
||||
: x == 0 ? type(x, ipart)
|
||||
: x == ipart ? type(T(0) * x, ipart)
|
||||
: type(sprout::math::copysign(x - ipart, x), ipart)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -30,7 +34,6 @@ namespace sprout {
|
|||
frac_int(FloatType x) {
|
||||
return sprout::math::detail::frac_int_impl(x, sprout::integer_part(x));
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -5,24 +5,34 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/integer_part.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
fractional_part_impl(T x, T ipart) {
|
||||
return x == ipart ? T(0) * x
|
||||
: sprout::math::copysign(x - ipart, x)
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename FloatType,
|
||||
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
|
||||
>
|
||||
inline SPROUT_CONSTEXPR FloatType
|
||||
fractional_part(FloatType x) {
|
||||
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
|
||||
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x - sprout::integer_part(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()
|
||||
: x == 0 ? x
|
||||
: sprout::math::detail::fractional_part_impl(x, sprout::integer_part(x))
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/math/trunc.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -19,11 +20,11 @@ namespace sprout {
|
|||
integer_part(FloatType x) {
|
||||
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
|
||||
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: sprout::math::isnan(x) ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: x == 0 ? x
|
||||
: sprout::math::trunc(x)
|
||||
;
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/math/iszero.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
|
@ -28,7 +29,8 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
issubnormal(FloatType x) {
|
||||
return !sprout::math::iszero(x)
|
||||
return !sprout::math::isnan(x)
|
||||
&& !sprout::math::iszero(x)
|
||||
&& sprout::math::detail::issubnormal_or_zero(x)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -28,7 +27,7 @@ namespace sprout {
|
|||
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
|
||||
: exp == 0 ? x
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::ldexp_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x), exp))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/log.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -31,7 +30,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::log1p(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::log1p_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -101,6 +101,10 @@ namespace sprout {
|
|||
logb(FloatType x) {
|
||||
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
|
||||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
# if defined(__GNUC__)
|
||||
: x == -std::numeric_limits<FloatType>::infinity()
|
||||
? std::numeric_limits<FloatType>::infinity()
|
||||
# endif
|
||||
: std::logb(x)
|
||||
#else
|
||||
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -28,7 +27,7 @@ namespace sprout {
|
|||
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
|
||||
: exp == 0 ? x
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::scalbln_impl<FloatType>(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x), exp))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -28,7 +27,7 @@ namespace sprout {
|
|||
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
|
||||
: exp == 0 ? x
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::scalbn_impl<FloatType>(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x), exp))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -15,10 +16,16 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
signbit(FloatType x) {
|
||||
return x < 0;
|
||||
return !sprout::math::isnan(x) && x < 0;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// bug:
|
||||
// signbit(-0) returns false .
|
||||
// # returns true . ( same as signbit(+0) )
|
||||
// signbit(-NaN) returns false .
|
||||
// # returns true . ( same as signbit(+NaN) )
|
||||
//
|
||||
using NS_SPROUT_MATH_DETAIL::signbit;
|
||||
} // namespace math
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/constants.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/cos.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -32,7 +31,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::sin(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::sin_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/factorial.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
|
@ -44,7 +43,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::sinh(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::sinh_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/isnan.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
@ -33,11 +34,10 @@ namespace sprout {
|
|||
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
|
||||
return x == 0 ? FloatType(0)
|
||||
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
|
||||
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
|
||||
: sprout::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)));
|
||||
}
|
||||
|
||||
template<
|
||||
typename IntType,
|
||||
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/cos.hpp>
|
||||
#include <sprout/math/sin.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
@ -31,7 +30,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::sin(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::tan_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/math/detail/config.hpp>
|
||||
#include <sprout/math/detail/float_compute.hpp>
|
||||
#include <sprout/math/copysign.hpp>
|
||||
#include <sprout/math/sinh.hpp>
|
||||
#include <sprout/math/cosh.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
@ -31,7 +30,7 @@ namespace sprout {
|
|||
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
|
||||
: std::tanh(x)
|
||||
#else
|
||||
: x == 0 ? sprout::math::copysign(FloatType(0), x)
|
||||
: x == 0 ? x
|
||||
: static_cast<FloatType>(sprout::math::detail::tanh_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))
|
||||
#endif
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue