From 2e2b6c96ab4ceb40bfde5aa235787642e82cfe37 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Fri, 26 Apr 2013 00:25:35 +0900 Subject: [PATCH] fix math functions --- sprout/math/asin.hpp | 3 +-- sprout/math/asinh.hpp | 3 +-- sprout/math/atan.hpp | 3 +-- sprout/math/atan2.hpp | 14 ++++++++++---- sprout/math/atanh.hpp | 3 +-- sprout/math/copysign.hpp | 12 ++++++++++-- sprout/math/expm1.hpp | 2 +- sprout/math/float2_exponent.hpp | 5 ++++- sprout/math/float2_sig_exp.hpp | 22 ++++++++++++---------- sprout/math/float2_significand.hpp | 10 +++++----- sprout/math/float_exponent.hpp | 5 ++++- sprout/math/float_sig_exp.hpp | 22 ++++++++++++---------- sprout/math/float_significand.hpp | 10 +++++----- sprout/math/fmax.hpp | 5 ++--- sprout/math/fmin.hpp | 5 ++--- sprout/math/frac_int.hpp | 11 +++++++---- sprout/math/fractional_part.hpp | 18 ++++++++++++++---- sprout/math/integer_part.hpp | 5 +++-- sprout/math/issubnormal.hpp | 4 +++- sprout/math/ldexp.hpp | 3 +-- sprout/math/log1p.hpp | 3 +-- sprout/math/logb.hpp | 4 ++++ sprout/math/scalbln.hpp | 3 +-- sprout/math/scalbn.hpp | 3 +-- sprout/math/signbit.hpp | 11 +++++++++-- sprout/math/sin.hpp | 3 +-- sprout/math/sinh.hpp | 3 +-- sprout/math/sqrt.hpp | 4 ++-- sprout/math/tan.hpp | 3 +-- sprout/math/tanh.hpp | 3 +-- 30 files changed, 121 insertions(+), 84 deletions(-) diff --git a/sprout/math/asin.hpp b/sprout/math/asin.hpp index f666e420..b01070a3 100644 --- a/sprout/math/asin.hpp +++ b/sprout/math/asin.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -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( x < 0 ? -sprout::math::detail::asin_impl(static_cast::type>(-x)) : sprout::math::detail::asin_impl(static_cast::type>(x)) diff --git a/sprout/math/asinh.hpp b/sprout/math/asinh.hpp index 0d4db6bc..16782d6c 100644 --- a/sprout/math/asinh.hpp +++ b/sprout/math/asinh.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -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(sprout::math::detail::asinh_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/atan.hpp b/sprout/math/atan.hpp index 250f9c29..3177e69f 100644 --- a/sprout/math/atan.hpp +++ b/sprout/math/atan.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include 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( x < 0 ? -sprout::math::detail::atan_impl(static_cast::type>(-x)) : sprout::math::detail::atan_impl(static_cast::type>(x)) diff --git a/sprout/math/atan2.hpp b/sprout/math/atan2.hpp index 749969e6..41cbba9e 100644 --- a/sprout/math/atan2.hpp +++ b/sprout/math/atan2.hpp @@ -40,7 +40,7 @@ namespace sprout { : x == std::numeric_limits::infinity() ? y == std::numeric_limits::infinity() ? sprout::math::quarter_pi() : y == -std::numeric_limits::infinity() ? -sprout::math::quarter_pi() - : sprout::math::copysign(FloatType(0), y) + : FloatType(0) * y : y == std::numeric_limits::infinity() ? sprout::math::half_pi() : y == -std::numeric_limits::infinity() ? -sprout::math::half_pi() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION @@ -48,9 +48,9 @@ namespace sprout { #else : y == 0 ? x < 0 ? sprout::math::copysign(sprout::math::pi(), y) - : x > 0 ? sprout::math::copysign(FloatType(0), y) + : x > 0 ? FloatType(0) * y : sprout::math::signbit(x) ? sprout::math::copysign(sprout::math::pi(), y) - : sprout::math::copysign(FloatType(0), y) + : FloatType(0) * y : x == 0 ? y < 0 ? -sprout::math::half_pi() : sprout::math::half_pi() @@ -76,7 +76,13 @@ namespace sprout { return sprout::math::detail::atan2(static_cast(y), static_cast(x)); } } // namespace detail - + // + // bug: + // atan2(}0, -0) returns } . + // # returns }0 . ( same as atan2(}0, +0) ) + // atan2(-0, x) returns - for x < 0. + // # returns + . ( same as atan2(+0, x) ) + // using sprout::math::detail::atan2; } // namespace math diff --git a/sprout/math/atanh.hpp b/sprout/math/atanh.hpp index 290bfdd2..d1280dac 100644 --- a/sprout/math/atanh.hpp +++ b/sprout/math/atanh.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -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(sprout::math::detail::atanh_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/copysign.hpp b/sprout/math/copysign.hpp index ff9c9aa4..5abbe557 100644 --- a/sprout/math/copysign.hpp +++ b/sprout/math/copysign.hpp @@ -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(x), static_cast(y)); } } // namespace detail - + // + // bug: + // copysign(}x, -0) returns -x for |x| > 0 . + // # returns +x . ( same as copysign(}x, +0) ) + // using NS_SPROUT_MATH_DETAIL::copysign; } // namespace math diff --git a/sprout/math/expm1.hpp b/sprout/math/expm1.hpp index 838e314f..ba3e1aa7 100644 --- a/sprout/math/expm1.hpp +++ b/sprout/math/expm1.hpp @@ -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(sprout::math::detail::expm1_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/float2_exponent.hpp b/sprout/math/float2_exponent.hpp index 70bbf5af..56db179d 100644 --- a/sprout/math/float2_exponent.hpp +++ b/sprout/math/float2_exponent.hpp @@ -1,11 +1,13 @@ #ifndef SPROUT_MATH_FLOAT2_EXPONENT_HPP #define SPROUT_MATH_FLOAT2_EXPONENT_HPP +#include #include #include #include #include #include +#include #include namespace sprout { @@ -18,10 +20,11 @@ namespace sprout { inline SPROUT_CONSTEXPR int float2_exponent(FloatType x) { return x == 0 ? 0 + : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? 0 + : sprout::math::isnan(x) ? FP_ILOGBNAN : sprout::math::ilogb2(x) + 1 ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/float2_sig_exp.hpp b/sprout/math/float2_sig_exp.hpp index a54317e7..527cac5a 100644 --- a/sprout/math/float2_sig_exp.hpp +++ b/sprout/math/float2_sig_exp.hpp @@ -1,12 +1,14 @@ #ifndef SPROUT_MATH_FLOAT2_SIG_EXP_HPP #define SPROUT_MATH_FLOAT2_SIG_EXP_HPP +#include #include #include #include -#include #include -#include +#include +#include +#include #include #include @@ -17,12 +19,7 @@ namespace sprout { inline SPROUT_CONSTEXPR sprout::pair float2_sig_exp_impl(T x, int exp) { typedef sprout::pair type; - return x == 0 ? type(T(0), exp) - : x == std::numeric_limits::infinity() ? type(std::numeric_limits::infinity(), exp) - : x == -std::numeric_limits::infinity() ? type(-std::numeric_limits::infinity(), exp) - : x == std::numeric_limits::quiet_NaN() ? type(std::numeric_limits::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 float2_sig_exp(FloatType x) { - return sprout::math::detail::float2_sig_exp_impl(x, sprout::math::float2_exponent(x)); + typedef sprout::pair type; + return x == std::numeric_limits::infinity() ? type(std::numeric_limits::infinity(), 0) + : x == -std::numeric_limits::infinity() ? type(-std::numeric_limits::infinity(), 0) + : sprout::math::isnan(x) ? type(std::numeric_limits::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::value>::type = sprout::enabler diff --git a/sprout/math/float2_significand.hpp b/sprout/math/float2_significand.hpp index e21a98c0..458ad711 100644 --- a/sprout/math/float2_significand.hpp +++ b/sprout/math/float2_significand.hpp @@ -4,8 +4,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -18,14 +19,13 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType float2_significand(FloatType x) { - return x == 0 ? FloatType(0) - : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() - : x == std::numeric_limits::quiet_NaN() ? std::numeric_limits::quiet_NaN() + : sprout::math::isnan(x) ? std::numeric_limits::quiet_NaN() + : x == 0 ? x : x / sprout::detail::pow_n(FloatType(2), sprout::float2_exponent(x)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/float_exponent.hpp b/sprout/math/float_exponent.hpp index 661dac6e..0ce6ea1c 100644 --- a/sprout/math/float_exponent.hpp +++ b/sprout/math/float_exponent.hpp @@ -1,11 +1,13 @@ #ifndef SPROUT_MATH_FLOAT_EXPONENT_HPP #define SPROUT_MATH_FLOAT_EXPONENT_HPP +#include #include #include #include #include #include +#include #include namespace sprout { @@ -18,10 +20,11 @@ namespace sprout { inline SPROUT_CONSTEXPR int float_exponent(FloatType x) { return x == 0 ? 0 + : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? 0 + : sprout::math::isnan(x) ? FP_ILOGBNAN : sprout::math::ilogb(x) + 1 ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/float_sig_exp.hpp b/sprout/math/float_sig_exp.hpp index 45d65e9d..66d0509e 100644 --- a/sprout/math/float_sig_exp.hpp +++ b/sprout/math/float_sig_exp.hpp @@ -1,12 +1,14 @@ #ifndef SPROUT_MATH_FLOAT_SIG_EXP_HPP #define SPROUT_MATH_FLOAT_SIG_EXP_HPP +#include #include #include #include -#include #include -#include +#include +#include +#include #include #include @@ -17,12 +19,7 @@ namespace sprout { inline SPROUT_CONSTEXPR sprout::pair float_sig_exp_impl(T x, int exp) { typedef sprout::pair type; - return x == 0 ? type(T(0), exp) - : x == std::numeric_limits::infinity() ? type(std::numeric_limits::infinity(), exp) - : x == -std::numeric_limits::infinity() ? type(-std::numeric_limits::infinity(), exp) - : x == std::numeric_limits::quiet_NaN() ? type(std::numeric_limits::quiet_NaN(), exp) - : type(x / sprout::detail::pow_n(T(std::numeric_limits::radix), exp), exp) - ; + return type(x / sprout::detail::pow_n(T(std::numeric_limits::radix), exp), exp); } template< @@ -31,9 +28,14 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::pair float_sig_exp(FloatType x) { - return sprout::math::detail::float_sig_exp_impl(x, sprout::float_exponent(x)); + typedef sprout::pair type; + return x == std::numeric_limits::infinity() ? type(std::numeric_limits::infinity(), 0) + : x == -std::numeric_limits::infinity() ? type(-std::numeric_limits::infinity(), 0) + : sprout::math::isnan(x) ? type(std::numeric_limits::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::value>::type = sprout::enabler diff --git a/sprout/math/float_significand.hpp b/sprout/math/float_significand.hpp index 792fdb72..9428c051 100644 --- a/sprout/math/float_significand.hpp +++ b/sprout/math/float_significand.hpp @@ -4,8 +4,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -18,14 +19,13 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType float_significand(FloatType x) { - return x == 0 ? FloatType(0) - : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() + return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() - : x == std::numeric_limits::quiet_NaN() ? std::numeric_limits::quiet_NaN() + : sprout::math::isnan(x) ? std::numeric_limits::quiet_NaN() + : x == 0 ? x : x / sprout::detail::pow_n(FloatType(std::numeric_limits::radix), sprout::float_exponent(x)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/fmax.hpp b/sprout/math/fmax.hpp index 3ec0bec5..f8ddf45e 100644 --- a/sprout/math/fmax.hpp +++ b/sprout/math/fmax.hpp @@ -1,10 +1,10 @@ #ifndef SPROUT_MATH_FMAX_HPP #define SPROUT_MATH_FMAX_HPP -#include #include #include #include +#include #include #include @@ -17,9 +17,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType fmax(FloatType x, FloatType y) { - return x < y && !y == std::numeric_limits::quiet_NaN() ? y : x; + return x < y && !sprout::math::isnan(y) ? y : x; } - template< typename ArithmeticType1, typename ArithmeticType2, diff --git a/sprout/math/fmin.hpp b/sprout/math/fmin.hpp index 4bf9cf4e..8429d925 100644 --- a/sprout/math/fmin.hpp +++ b/sprout/math/fmin.hpp @@ -1,10 +1,10 @@ #ifndef SPROUT_MATH_FMIN_HPP #define SPROUT_MATH_FMIN_HPP -#include #include #include #include +#include #include #include @@ -17,9 +17,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType fmin(FloatType x, FloatType y) { - return x > y && !y == std::numeric_limits::quiet_NaN() ? y : x; + return y < x && !sprout::math::isnan(y) ? y : x; } - template< typename ArithmeticType1, typename ArithmeticType2, diff --git a/sprout/math/frac_int.hpp b/sprout/math/frac_int.hpp index 7cb84fb0..9a7ca9a0 100644 --- a/sprout/math/frac_int.hpp +++ b/sprout/math/frac_int.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -16,9 +18,11 @@ namespace sprout { inline SPROUT_CONSTEXPR sprout::pair frac_int_impl(T x, T ipart) { typedef sprout::pair type; - return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? type(T(0), ipart) - : x == std::numeric_limits::quiet_NaN() ? type(std::numeric_limits::quiet_NaN(), ipart) - : type(x - ipart, ipart) + return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? type(sprout::math::copysign(T(0), x), ipart) + : sprout::math::isnan(x) ? type(std::numeric_limits::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::value>::type = sprout::enabler diff --git a/sprout/math/fractional_part.hpp b/sprout/math/fractional_part.hpp index c8e53c80..8c76d04a 100644 --- a/sprout/math/fractional_part.hpp +++ b/sprout/math/fractional_part.hpp @@ -5,24 +5,34 @@ #include #include #include +#include +#include #include #include namespace sprout { namespace math { namespace detail { + template + 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::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType fractional_part(FloatType x) { - return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? FloatType(0) - : x == std::numeric_limits::quiet_NaN() ? std::numeric_limits::quiet_NaN() - : x - sprout::integer_part(x) + return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() ? sprout::math::copysign(FloatType(0), x) + : sprout::math::isnan(x) ? std::numeric_limits::quiet_NaN() + : x == 0 ? x + : sprout::math::detail::fractional_part_impl(x, sprout::integer_part(x)) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/integer_part.hpp b/sprout/math/integer_part.hpp index 338fa39e..56ada502 100644 --- a/sprout/math/integer_part.hpp +++ b/sprout/math/integer_part.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -19,11 +20,11 @@ namespace sprout { integer_part(FloatType x) { return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() - : x == std::numeric_limits::quiet_NaN() ? std::numeric_limits::quiet_NaN() + : sprout::math::isnan(x) ? std::numeric_limits::quiet_NaN() + : x == 0 ? x : sprout::math::trunc(x) ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/issubnormal.hpp b/sprout/math/issubnormal.hpp index a1bfc955..5a687ff4 100644 --- a/sprout/math/issubnormal.hpp +++ b/sprout/math/issubnormal.hpp @@ -6,6 +6,7 @@ #include #include #include +#include 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) ; } diff --git a/sprout/math/ldexp.hpp b/sprout/math/ldexp.hpp index 8eda68c6..fd880849 100644 --- a/sprout/math/ldexp.hpp +++ b/sprout/math/ldexp.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -28,7 +27,7 @@ namespace sprout { return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : exp == 0 ? x - : x == 0 ? sprout::math::copysign(FloatType(0), x) + : x == 0 ? x : static_cast(sprout::math::detail::ldexp_impl(static_cast::type>(x), exp)) ; } diff --git a/sprout/math/log1p.hpp b/sprout/math/log1p.hpp index cad4e88d..6182f313 100644 --- a/sprout/math/log1p.hpp +++ b/sprout/math/log1p.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -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(sprout::math::detail::log1p_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/logb.hpp b/sprout/math/logb.hpp index 209c4a07..27c2a166 100644 --- a/sprout/math/logb.hpp +++ b/sprout/math/logb.hpp @@ -101,6 +101,10 @@ namespace sprout { logb(FloatType x) { return x == 0 ? -std::numeric_limits::infinity() #if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# if defined(__GNUC__) + : x == -std::numeric_limits::infinity() + ? std::numeric_limits::infinity() +# endif : std::logb(x) #else : x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity() diff --git a/sprout/math/scalbln.hpp b/sprout/math/scalbln.hpp index f9d757d7..4a8630ff 100644 --- a/sprout/math/scalbln.hpp +++ b/sprout/math/scalbln.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -28,7 +27,7 @@ namespace sprout { return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : exp == 0 ? x - : x == 0 ? sprout::math::copysign(FloatType(0), x) + : x == 0 ? x : static_cast(sprout::math::detail::scalbln_impl(static_cast::type>(x), exp)) ; } diff --git a/sprout/math/scalbn.hpp b/sprout/math/scalbn.hpp index 2309b9fa..90afe13e 100644 --- a/sprout/math/scalbn.hpp +++ b/sprout/math/scalbn.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -28,7 +27,7 @@ namespace sprout { return x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() : x == -std::numeric_limits::infinity() ? -std::numeric_limits::infinity() : exp == 0 ? x - : x == 0 ? sprout::math::copysign(FloatType(0), x) + : x == 0 ? x : static_cast(sprout::math::detail::scalbn_impl(static_cast::type>(x), exp)) ; } diff --git a/sprout/math/signbit.hpp b/sprout/math/signbit.hpp index 91d2e09b..40de7814 100644 --- a/sprout/math/signbit.hpp +++ b/sprout/math/signbit.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include 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 diff --git a/sprout/math/sin.hpp b/sprout/math/sin.hpp index c6dcaf85..9d4ef31b 100644 --- a/sprout/math/sin.hpp +++ b/sprout/math/sin.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -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(sprout::math::detail::sin_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/sinh.hpp b/sprout/math/sinh.hpp index 1cdf4a3d..e6e06738 100644 --- a/sprout/math/sinh.hpp +++ b/sprout/math/sinh.hpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -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(sprout::math::detail::sinh_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/sqrt.hpp b/sprout/math/sqrt.hpp index ed4d50c4..7cd77fec 100644 --- a/sprout/math/sqrt.hpp +++ b/sprout/math/sqrt.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace sprout { @@ -33,11 +34,10 @@ namespace sprout { typedef typename sprout::math::detail::float_compute::type type; return x == 0 ? FloatType(0) : x == std::numeric_limits::infinity() ? std::numeric_limits::infinity() - : x == std::numeric_limits::quiet_NaN() ? std::numeric_limits::quiet_NaN() + : sprout::math::isnan(x) ? std::numeric_limits::quiet_NaN() : x < 0 ? std::numeric_limits::quiet_NaN() : static_cast(sprout::math::detail::sqrt_impl(static_cast(x), x > 1 ? static_cast(x) : type(1))); } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/math/tan.hpp b/sprout/math/tan.hpp index 4d29f769..c007949e 100644 --- a/sprout/math/tan.hpp +++ b/sprout/math/tan.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -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(sprout::math::detail::tan_impl(static_cast::type>(x))) #endif ; diff --git a/sprout/math/tanh.hpp b/sprout/math/tanh.hpp index f3e32f11..6d28063d 100644 --- a/sprout/math/tanh.hpp +++ b/sprout/math/tanh.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -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(sprout::math::detail::tanh_impl(static_cast::type>(x))) #endif ;