fix math functions

This commit is contained in:
bolero-MURAKAMI 2013-04-26 00:25:35 +09:00
parent dad3acceea
commit 2e2b6c96ab
30 changed files with 121 additions and 84 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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