From ffb876c930df2c5acc2afa4f0d2cfa3f629654e6 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Mon, 29 Apr 2013 10:56:46 +0900 Subject: [PATCH] fix math functions --- sprout/math.hpp | 1 + sprout/math/acos.hpp | 6 ++++-- sprout/math/acosh.hpp | 4 +++- sprout/math/asin.hpp | 4 +++- sprout/math/asinh.hpp | 4 +++- sprout/math/atan.hpp | 4 +++- sprout/math/atan2.hpp | 15 +++++++++++++-- sprout/math/atanh.hpp | 6 ++++-- sprout/math/constants.hpp | 5 +++++ sprout/math/copysign.hpp | 19 ++++++++++++++----- sprout/math/cos.hpp | 9 +++++---- sprout/math/cosh.hpp | 5 +++-- sprout/math/isfinite.hpp | 2 +- sprout/math/isinf.hpp | 2 +- sprout/math/isnan.hpp | 2 +- sprout/math/isnormal.hpp | 2 +- sprout/math/issubnormal.hpp | 4 ++-- sprout/math/iszero.hpp | 2 +- sprout/math/signbit.hpp | 3 ++- sprout/math/sin.hpp | 7 ++++--- sprout/math/sinh.hpp | 4 +++- sprout/math/tan.hpp | 8 +++++--- sprout/math/tanh.hpp | 4 +++- 23 files changed, 85 insertions(+), 37 deletions(-) diff --git a/sprout/math.hpp b/sprout/math.hpp index b6ea1eba..05c8ba2f 100644 --- a/sprout/math.hpp +++ b/sprout/math.hpp @@ -3,5 +3,6 @@ #include #include +#include #endif // #ifndef SPROUT_MATH_HPP diff --git a/sprout/math/acos.hpp b/sprout/math/acos.hpp index dc5c71fe..84cddb41 100644 --- a/sprout/math/acos.hpp +++ b/sprout/math/acos.hpp @@ -6,9 +6,10 @@ #include #include #include +#include +#include #include #include -#include #include namespace sprout { @@ -26,7 +27,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType acos(FloatType x) { - return sprout::math::fabs(x) > 1 ? std::numeric_limits::quiet_NaN() + return sprout::math::isnan(x) ? x + : sprout::math::fabs(x) > 1 ? std::numeric_limits::quiet_NaN() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::acos(x) #else diff --git a/sprout/math/acosh.hpp b/sprout/math/acosh.hpp index 38423d86..0fb5f546 100644 --- a/sprout/math/acosh.hpp +++ b/sprout/math/acosh.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType acosh(FloatType x) { - return x < 1 ? std::numeric_limits::quiet_NaN() + return sprout::math::isnan(x) ? x + : x < 1 ? -std::numeric_limits::quiet_NaN() : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::acosh(x) diff --git a/sprout/math/asin.hpp b/sprout/math/asin.hpp index b01070a3..14304e06 100644 --- a/sprout/math/asin.hpp +++ b/sprout/math/asin.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType asin(FloatType x) { - return sprout::math::fabs(x) > 1 ? std::numeric_limits::quiet_NaN() + return sprout::math::isnan(x) ? x + : sprout::math::fabs(x) > 1 ? std::numeric_limits::quiet_NaN() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::asin(x) #else diff --git a/sprout/math/asinh.hpp b/sprout/math/asinh.hpp index 16782d6c..673f4ffd 100644 --- a/sprout/math/asinh.hpp +++ b/sprout/math/asinh.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType asinh(FloatType x) { - return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::asinh(x) diff --git a/sprout/math/atan.hpp b/sprout/math/atan.hpp index 3177e69f..c68cf2f8 100644 --- a/sprout/math/atan.hpp +++ b/sprout/math/atan.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace sprout { @@ -41,7 +42,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType atan(FloatType x) { - return x == std::numeric_limits::infinity() ? sprout::math::half_pi() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() ? sprout::math::half_pi() : x == -std::numeric_limits::infinity() ? -sprout::math::half_pi() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::atan(x) diff --git a/sprout/math/atan2.hpp b/sprout/math/atan2.hpp index 41cbba9e..1faef1ff 100644 --- a/sprout/math/atan2.hpp +++ b/sprout/math/atan2.hpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -33,7 +35,13 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType atan2(FloatType y, FloatType x) { - return x == -std::numeric_limits::infinity() + return sprout::math::isnan(y) + ? sprout::math::isnan(x) + ? sprout::math::signbit(y) && sprout::math::signbit(x) ? -std::numeric_limits::quiet_NaN() + : std::numeric_limits::quiet_NaN() + : y + : sprout::math::isnan(x) ? x + : x == -std::numeric_limits::infinity() ? y == std::numeric_limits::infinity() ? sprout::math::three_quarters_pi() : y == -std::numeric_limits::infinity() ? -sprout::math::three_quarters_pi() : sprout::math::copysign(sprout::math::pi(), y) @@ -77,11 +85,14 @@ namespace sprout { } } // namespace detail // - // bug: + // issue: + // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] // atan2(}0, -0) returns } . // # returns }0 . ( same as atan2(}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 diff --git a/sprout/math/atanh.hpp b/sprout/math/atanh.hpp index d1280dac..ad85ebfd 100644 --- a/sprout/math/atanh.hpp +++ b/sprout/math/atanh.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +26,10 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType atanh(FloatType x) { - return x == 1 ? std::numeric_limits::infinity() + return sprout::math::isnan(x) ? x + : x == 1 ? std::numeric_limits::infinity() : x == -1 ? -std::numeric_limits::infinity() - : sprout::math::fabs(x) > 1 ? std::numeric_limits::quiet_NaN() + : sprout::math::fabs(x) > 1 ? -std::numeric_limits::quiet_NaN() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::atanh(x) #else diff --git a/sprout/math/constants.hpp b/sprout/math/constants.hpp index 77af9ebb..86f824b7 100644 --- a/sprout/math/constants.hpp +++ b/sprout/math/constants.hpp @@ -91,6 +91,7 @@ namespace sprout { } // // half + // quarter // third // twothirds // @@ -99,6 +100,10 @@ namespace sprout { return 0.5L; } template + inline SPROUT_CONSTEXPR T quarter() { + return 0.25L; + } + template inline SPROUT_CONSTEXPR T third() { return 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333L; } diff --git a/sprout/math/copysign.hpp b/sprout/math/copysign.hpp index 5abbe557..5df0a45a 100644 --- a/sprout/math/copysign.hpp +++ b/sprout/math/copysign.hpp @@ -1,9 +1,11 @@ #ifndef SPROUT_MATH_COPYSIGN_HPP #define SPROUT_MATH_COPYSIGN_HPP +#include #include #include #include +#include #include #include #include @@ -18,9 +20,13 @@ namespace sprout { inline SPROUT_CONSTEXPR FloatType copysign(FloatType x, FloatType y) { return x == 0 - ? y == 0 ? y - : sprout::math::signbit(y) ? -FloatType(0) - : FloatType(0) + ? 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::quiet_NaN() + : std::numeric_limits::quiet_NaN() : sprout::math::signbit(y) != sprout::math::signbit(x) ? -x : x ; @@ -39,9 +45,12 @@ namespace sprout { } } // namespace detail // - // bug: - // copysign(}x, -0) returns -x for |x| > 0 . + // issue: + // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] + // copysign(}x, -0) returns -x for |x| is not 0 . // # returns +x . ( same as copysign(}x, +0) ) + // copysign(}x, -NaN) returns -x for |x| is not NaN . + // # returns +x . ( same as copysign(}x, +NaN) ) // using NS_SPROUT_MATH_DETAIL::copysign; } // namespace math diff --git a/sprout/math/cos.hpp b/sprout/math/cos.hpp index 114962b4..a1389c8f 100644 --- a/sprout/math/cos.hpp +++ b/sprout/math/cos.hpp @@ -8,8 +8,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -40,9 +41,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType cos(FloatType x) { - return x == std::numeric_limits::infinity() - || x == -std::numeric_limits::infinity() - ? std::numeric_limits::quiet_NaN() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() + ? -std::numeric_limits::quiet_NaN() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::cos(x) #else diff --git a/sprout/math/cosh.hpp b/sprout/math/cosh.hpp index 8ad25913..af8e0c20 100644 --- a/sprout/math/cosh.hpp +++ b/sprout/math/cosh.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -38,8 +39,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType cosh(FloatType x) { - return x == std::numeric_limits::infinity() - || x == -std::numeric_limits::infinity() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? std::numeric_limits::infinity() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::cosh(x) diff --git a/sprout/math/isfinite.hpp b/sprout/math/isfinite.hpp index 0228ce8e..7b7cc544 100644 --- a/sprout/math/isfinite.hpp +++ b/sprout/math/isfinite.hpp @@ -15,7 +15,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool isfinite(FloatType x) { return !sprout::math::isnan(x) && !sprout::math::isinf(x) diff --git a/sprout/math/isinf.hpp b/sprout/math/isinf.hpp index de6f7d87..81db067a 100644 --- a/sprout/math/isinf.hpp +++ b/sprout/math/isinf.hpp @@ -14,7 +14,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool isinf(FloatType x) { return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() diff --git a/sprout/math/isnan.hpp b/sprout/math/isnan.hpp index 892f9f71..e4e235c8 100644 --- a/sprout/math/isnan.hpp +++ b/sprout/math/isnan.hpp @@ -13,7 +13,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool isnan(FloatType x) { return !(x == x); } diff --git a/sprout/math/isnormal.hpp b/sprout/math/isnormal.hpp index 315674c7..b4f78b2d 100644 --- a/sprout/math/isnormal.hpp +++ b/sprout/math/isnormal.hpp @@ -16,7 +16,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool isnormal(FloatType x) { return !sprout::math::isnan(x) && !sprout::math::isinf(x) diff --git a/sprout/math/issubnormal.hpp b/sprout/math/issubnormal.hpp index 5a687ff4..c1cd0d16 100644 --- a/sprout/math/issubnormal.hpp +++ b/sprout/math/issubnormal.hpp @@ -15,7 +15,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool issubnormal_or_zero(FloatType x) { return x > 0 ? x < std::numeric_limits::min() @@ -27,7 +27,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool issubnormal(FloatType x) { return !sprout::math::isnan(x) && !sprout::math::iszero(x) diff --git a/sprout/math/iszero.hpp b/sprout/math/iszero.hpp index db708834..b653ebd5 100644 --- a/sprout/math/iszero.hpp +++ b/sprout/math/iszero.hpp @@ -12,7 +12,7 @@ namespace sprout { typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > - inline SPROUT_CONSTEXPR int + inline SPROUT_CONSTEXPR bool iszero(FloatType x) { return x == 0; } diff --git a/sprout/math/signbit.hpp b/sprout/math/signbit.hpp index 40de7814..afda7937 100644 --- a/sprout/math/signbit.hpp +++ b/sprout/math/signbit.hpp @@ -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 . diff --git a/sprout/math/sin.hpp b/sprout/math/sin.hpp index 9d4ef31b..e65ae171 100644 --- a/sprout/math/sin.hpp +++ b/sprout/math/sin.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -25,9 +26,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType sin(FloatType x) { - return x == std::numeric_limits::infinity() - || x == -std::numeric_limits::infinity() - ? std::numeric_limits::quiet_NaN() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() + ? -std::numeric_limits::quiet_NaN() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::sin(x) #else diff --git a/sprout/math/sinh.hpp b/sprout/math/sinh.hpp index e6e06738..adf355ab 100644 --- a/sprout/math/sinh.hpp +++ b/sprout/math/sinh.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType sinh(FloatType x) { - return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::sinh(x) diff --git a/sprout/math/tan.hpp b/sprout/math/tan.hpp index c007949e..a95432e2 100644 --- a/sprout/math/tan.hpp +++ b/sprout/math/tan.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -25,10 +26,11 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType tan(FloatType x) { - return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() - ? std::numeric_limits::quiet_NaN() + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() + ? -std::numeric_limits::quiet_NaN() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION - : std::sin(x) + : std::tan(x) #else : x == 0 ? x : static_cast(sprout::math::detail::tan_impl(static_cast::type>(x))) diff --git a/sprout/math/tanh.hpp b/sprout/math/tanh.hpp index 6d28063d..0bd1d9db 100644 --- a/sprout/math/tanh.hpp +++ b/sprout/math/tanh.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType tanh(FloatType x) { - return x == std::numeric_limits::infinity() ? FloatType(1) + return sprout::math::isnan(x) ? x + : x == std::numeric_limits::infinity() ? FloatType(1) : x == -std::numeric_limits::infinity() ? FloatType(-1) #if SPROUT_USE_BUILTIN_CMATH_FUNCTION : std::tanh(x)