fix math functions

This commit is contained in:
bolero-MURAKAMI 2013-04-29 10:56:46 +09:00
parent 2e2b6c96ab
commit ffb876c930
23 changed files with 85 additions and 37 deletions

View file

@ -3,5 +3,6 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/functions.hpp> #include <sprout/math/functions.hpp>
#include <sprout/math/constants.hpp>
#endif // #ifndef SPROUT_MATH_HPP #endif // #ifndef SPROUT_MATH_HPP

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/asin.hpp> #include <sprout/math/asin.hpp>
#include <sprout/math/fabs.hpp> #include <sprout/math/fabs.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
acos(FloatType x) { acos(FloatType x) {
return sprout::math::fabs(x) > 1 ? std::numeric_limits<FloatType>::quiet_NaN() return sprout::math::isnan(x) ? x
: sprout::math::fabs(x) > 1 ? std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::acos(x) : std::acos(x)
#else #else

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/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
acosh(FloatType x) { acosh(FloatType x) {
return x < 1 ? std::numeric_limits<FloatType>::quiet_NaN() return sprout::math::isnan(x) ? x
: x < 1 ? -std::numeric_limits<FloatType>::quiet_NaN()
: 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::acosh(x) : std::acosh(x)

View file

@ -10,6 +10,7 @@
#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/factorial.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>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
@ -43,7 +44,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
asin(FloatType x) { asin(FloatType x) {
return sprout::math::fabs(x) > 1 ? std::numeric_limits<FloatType>::quiet_NaN() return sprout::math::isnan(x) ? x
: sprout::math::fabs(x) > 1 ? std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::asin(x) : std::asin(x)
#else #else

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/math/sqrt.hpp> #include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
asinh(FloatType x) { asinh(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() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::asinh(x) : std::asinh(x)

View file

@ -10,6 +10,7 @@
#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/factorial.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -41,7 +42,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
atan(FloatType x) { atan(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>() return sprout::math::isnan(x) ? x
: x == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>()
: x == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>() : x == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::atan(x) : std::atan(x)

View file

@ -7,6 +7,8 @@
#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/signbit.hpp>
#include <sprout/math/copysign.hpp> #include <sprout/math/copysign.hpp>
#include <sprout/math/signbit.hpp> #include <sprout/math/signbit.hpp>
#include <sprout/math/atan.hpp> #include <sprout/math/atan.hpp>
@ -33,7 +35,13 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
atan2(FloatType y, FloatType x) { atan2(FloatType y, FloatType x) {
return x == -std::numeric_limits<FloatType>::infinity() 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()
: y
: sprout::math::isnan(x) ? x
: x == -std::numeric_limits<FloatType>::infinity()
? y == std::numeric_limits<FloatType>::infinity() ? sprout::math::three_quarters_pi<FloatType>() ? y == std::numeric_limits<FloatType>::infinity() ? sprout::math::three_quarters_pi<FloatType>()
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::three_quarters_pi<FloatType>() : y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::three_quarters_pi<FloatType>()
: sprout::math::copysign(sprout::math::pi<FloatType>(), y) : sprout::math::copysign(sprout::math::pi<FloatType>(), y)
@ -77,11 +85,14 @@ namespace sprout {
} }
} // namespace detail } // namespace detail
// //
// bug: // issue:
// [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
// atan2(<28>}0, -0) returns <20>}ƒÎ . // atan2(<28>}0, -0) returns <20>}ƒÎ .
// # returns <20>}0 . ( same as atan2(<28>}0, +0) ) // # returns <20>}0 . ( same as atan2(<28>}0, +0) )
// atan2(-0, x) returns -ƒÎ for x < 0. // atan2(-0, x) returns -ƒÎ for x < 0.
// # returns +ƒÎ . ( same as atan2(+0, x) ) // # returns +ƒÎ . ( same as atan2(+0, x) )
// atan2(-NaN, -NaN) returns -NaN .
// # returns +NaN . ( same as atan2(+NaN, +NaN) )
// //
using sprout::math::detail::atan2; using sprout::math::detail::atan2;
} // namespace math } // namespace math

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

View file

@ -91,6 +91,7 @@ namespace sprout {
} }
// //
// half // half
// quarter
// third // third
// twothirds // twothirds
// //
@ -99,6 +100,10 @@ namespace sprout {
return 0.5L; return 0.5L;
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T quarter() {
return 0.25L;
}
template<typename T>
inline SPROUT_CONSTEXPR T third() { inline SPROUT_CONSTEXPR T third() {
return 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333L; return 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333L;
} }

View file

@ -1,9 +1,11 @@
#ifndef SPROUT_MATH_COPYSIGN_HPP #ifndef SPROUT_MATH_COPYSIGN_HPP
#define SPROUT_MATH_COPYSIGN_HPP #define SPROUT_MATH_COPYSIGN_HPP
#include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/signbit.hpp> #include <sprout/math/signbit.hpp>
#include <sprout/type_traits/float_promote.hpp> #include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
@ -18,9 +20,13 @@ namespace sprout {
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
copysign(FloatType x, FloatType y) { copysign(FloatType x, FloatType y) {
return x == 0 return x == 0
? y == 0 ? y ? y == 0 ? y
: sprout::math::signbit(y) ? -FloatType(0) : sprout::math::signbit(y) ? -FloatType(0)
: FloatType(0) : FloatType(0)
: sprout::math::isnan(x)
? sprout::math::isnan(y) ? y
: sprout::math::signbit(y) ? -std::numeric_limits<FloatType>::quiet_NaN()
: std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::signbit(y) != sprout::math::signbit(x) ? -x : sprout::math::signbit(y) != sprout::math::signbit(x) ? -x
: x : x
; ;
@ -39,9 +45,12 @@ namespace sprout {
} }
} // namespace detail } // namespace detail
// //
// bug: // issue:
// copysign(<28>}x, -0) returns -x for |x| > 0 . // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
// copysign(<28>}x, -0) returns -x for |x| is not 0 .
// # returns +x . ( same as copysign(<28>}x, +0) ) // # returns +x . ( same as copysign(<28>}x, +0) )
// copysign(<28>}x, -NaN) returns -x for |x| is not NaN .
// # returns +x . ( same as copysign(<28>}x, +NaN) )
// //
using NS_SPROUT_MATH_DETAIL::copysign; using NS_SPROUT_MATH_DETAIL::copysign;
} // namespace math } // namespace math

View file

@ -8,8 +8,9 @@
#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/factorial.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/math/isnan.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>
@ -40,9 +41,9 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
cos(FloatType x) { cos(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
|| x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN() ? -std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::cos(x) : std::cos(x)
#else #else

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>
@ -38,8 +39,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
cosh(FloatType x) { cosh(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
|| 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()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::cosh(x) : std::cosh(x)

View file

@ -15,7 +15,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
isfinite(FloatType x) { isfinite(FloatType x) {
return !sprout::math::isnan(x) return !sprout::math::isnan(x)
&& !sprout::math::isinf(x) && !sprout::math::isinf(x)

View file

@ -14,7 +14,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
isinf(FloatType x) { isinf(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() return x == std::numeric_limits<FloatType>::infinity()
|| x == -std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()

View file

@ -13,7 +13,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
isnan(FloatType x) { isnan(FloatType x) {
return !(x == x); return !(x == x);
} }

View file

@ -16,7 +16,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
isnormal(FloatType x) { isnormal(FloatType x) {
return !sprout::math::isnan(x) return !sprout::math::isnan(x)
&& !sprout::math::isinf(x) && !sprout::math::isinf(x)

View file

@ -15,7 +15,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
issubnormal_or_zero(FloatType x) { issubnormal_or_zero(FloatType x) {
return x > 0 return x > 0
? x < std::numeric_limits<double>::min() ? x < std::numeric_limits<double>::min()
@ -27,7 +27,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
issubnormal(FloatType x) { issubnormal(FloatType x) {
return !sprout::math::isnan(x) return !sprout::math::isnan(x)
&& !sprout::math::iszero(x) && !sprout::math::iszero(x)

View file

@ -12,7 +12,7 @@ namespace sprout {
typename FloatType, typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR bool
iszero(FloatType x) { iszero(FloatType x) {
return x == 0; return x == 0;
} }

View file

@ -20,7 +20,8 @@ namespace sprout {
} }
} // namespace detail } // namespace detail
// //
// bug: // issue:
// [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
// signbit(-0) returns false . // signbit(-0) returns false .
// # returns true . ( same as signbit(+0) ) // # returns true . ( same as signbit(+0) )
// signbit(-NaN) returns false . // signbit(-NaN) returns false .

View file

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

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>
@ -38,7 +39,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
sinh(FloatType x) { sinh(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() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::sinh(x) : std::sinh(x)

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/cos.hpp> #include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp> #include <sprout/math/sin.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
@ -25,10 +26,11 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
tan(FloatType x) { tan(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() return sprout::math::isnan(x) ? x
? std::numeric_limits<FloatType>::quiet_NaN() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? -std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::sin(x) : std::tan(x)
#else #else
: x == 0 ? x : x == 0 ? x
: static_cast<FloatType>(sprout::math::detail::tan_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x))) : static_cast<FloatType>(sprout::math::detail::tan_impl(static_cast<typename sprout::math::detail::float_compute<FloatType>::type>(x)))

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/sinh.hpp> #include <sprout/math/sinh.hpp>
#include <sprout/math/cosh.hpp> #include <sprout/math/cosh.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
@ -25,7 +26,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
tanh(FloatType x) { tanh(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() ? FloatType(-1) : x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION #if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::tanh(x) : std::tanh(x)