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/math/functions.hpp>
#include <sprout/math/constants.hpp>
#endif // #ifndef SPROUT_MATH_HPP

View file

@ -6,9 +6,10 @@
#include <sprout/config.hpp>
#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/asin.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
@ -26,7 +27,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
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
: std::acos(x)
#else

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

View file

@ -10,6 +10,7 @@
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -43,7 +44,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
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
: std::asin(x)
#else

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

View file

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

View file

@ -7,6 +7,8 @@
#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/signbit.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/math/signbit.hpp>
#include <sprout/math/atan.hpp>
@ -33,7 +35,13 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
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>()
: sprout::math::copysign(sprout::math::pi<FloatType>(), y)
@ -77,11 +85,14 @@ namespace sprout {
}
} // namespace detail
//
// bug:
// issue:
// [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
// 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) )
// atan2(-NaN, -NaN) returns -NaN .
// # returns +NaN . ( same as atan2(+NaN, +NaN) )
//
using sprout::math::detail::atan2;
} // namespace math

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/math/log.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -25,9 +26,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
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()
: 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
: std::atanh(x)
#else

View file

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

View file

@ -1,9 +1,11 @@
#ifndef SPROUT_MATH_COPYSIGN_HPP
#define SPROUT_MATH_COPYSIGN_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/signbit.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -21,6 +23,10 @@ namespace sprout {
? y == 0 ? y
: sprout::math::signbit(y) ? -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
: x
;
@ -39,9 +45,12 @@ namespace sprout {
}
} // namespace detail
//
// bug:
// copysign(<28>}x, -0) returns -x for |x| > 0 .
// issue:
// [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ]
// copysign(<28>}x, -0) returns -x for |x| is not 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;
} // namespace math

View file

@ -8,8 +8,9 @@
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/fmod.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -40,9 +41,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
cos(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity()
|| x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN()
return sprout::math::isnan(x) ? x
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? -std::numeric_limits<FloatType>::quiet_NaN()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::cos(x)
#else

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,6 +8,7 @@
#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/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -38,7 +39,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
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()
#if SPROUT_USE_BUILTIN_CMATH_FUNCTION
: std::sinh(x)

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