diff --git a/sprout/complex/nearest.hpp b/sprout/complex/nearest.hpp index 0f2858bd..c5a5c9ad 100644 --- a/sprout/complex/nearest.hpp +++ b/sprout/complex/nearest.hpp @@ -12,12 +12,12 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::complex ceil(sprout::complex const& x) { - return sprout::complex(sprout::ceil(x.real()), sprout::ceil(x.imag())); + return sprout::complex(sprout::math::ceil(x.real()), sprout::math::ceil(x.imag())); } template inline SPROUT_CONSTEXPR sprout::complex floor(sprout::complex const& x) { - return sprout::complex(sprout::floor(x.real()), sprout::floor(x.imag())); + return sprout::complex(sprout::math::floor(x.real()), sprout::math::floor(x.imag())); } template inline SPROUT_CONSTEXPR sprout::complex @@ -27,7 +27,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::complex round(sprout::complex const& x) { - return sprout::complex(sprout::round(x.real()), sprout::round(x.imag())); + return sprout::complex(sprout::math::round(x.real()), sprout::math::round(x.imag())); } } // namespace sprout diff --git a/sprout/detail/math/float.hpp b/sprout/detail/math/float.hpp index 67984328..159bb062 100644 --- a/sprout/detail/math/float.hpp +++ b/sprout/detail/math/float.hpp @@ -103,7 +103,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR int float_digit_of_impl(FloatType val) { - return static_cast((val - sprout::floor(val)) * 10); + return static_cast((val - sprout::math::floor(val)) * 10); } template inline SPROUT_CONSTEXPR int @@ -120,7 +120,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType float_round_impl(FloatType val, FloatType p10) { - return sprout::round(val * p10) / p10; + return sprout::math::round(val * p10) / p10; } template inline SPROUT_CONSTEXPR FloatType diff --git a/sprout/math/ceil.hpp b/sprout/math/ceil.hpp index e853494f..bd231a90 100644 --- a/sprout/math/ceil.hpp +++ b/sprout/math/ceil.hpp @@ -7,35 +7,48 @@ #include #include #include +#include +#include #include #include namespace sprout { namespace math { namespace detail { - template - inline SPROUT_CONSTEXPR FloatType - ceil_impl(FloatType x, FloatType x0) { + template + inline SPROUT_CONSTEXPR T + ceil_impl_1(T x, T x0) { return sprout::math::equal_to(x, x0) ? x0 - : x0 + 1 + : x0 + T(1) + ; + } + template + inline SPROUT_CONSTEXPR T + ceil_impl(T x) { + return x < 0 ? -static_cast(static_cast(-x)) + : sprout::math::detail::ceil_impl_1(x, static_cast(static_cast(x))) ; } + template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType ceil(FloatType x) { - return x == 0 ? FloatType(0) + 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::ceil(x) +#else + : x == 0 ? x : std::numeric_limits::max() < x || std::numeric_limits::max() < -x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("ceil: large float rounding."), x) - : x < 0 ? -static_cast(static_cast(-x)) - : sprout::math::detail::ceil_impl(x, static_cast(static_cast(x))) + : static_cast(sprout::math::detail::ceil_impl(static_cast::type>(x))) +#endif ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler @@ -46,7 +59,7 @@ namespace sprout { } } // namespace detail - using NS_SPROUT_MATH_DETAIL::ceil; + using sprout::math::detail::ceil; } // namespace math using sprout::math::ceil; diff --git a/sprout/math/floor.hpp b/sprout/math/floor.hpp index 684af967..970acec4 100644 --- a/sprout/math/floor.hpp +++ b/sprout/math/floor.hpp @@ -7,35 +7,48 @@ #include #include #include +#include +#include #include #include namespace sprout { namespace math { namespace detail { - template - inline SPROUT_CONSTEXPR FloatType - floor_impl(FloatType x, FloatType x0) { + template + inline SPROUT_CONSTEXPR T + floor_impl_1(T x, T x0) { return sprout::math::equal_to(x, x0) ? x0 - : x0 - 1 + : x0 - T(1) + ; + } + template + inline SPROUT_CONSTEXPR T + floor_impl(T x) { + return x < 0 ? sprout::math::detail::floor_impl_1(x, -static_cast(static_cast(-x))) + : static_cast(static_cast(x)) ; } + template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType floor(FloatType x) { - return x == 0 ? FloatType(0) + 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::floor(x) +#else + : x == 0 ? x : std::numeric_limits::max() < x || std::numeric_limits::max() < -x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("floor: large float rounding."), x) - : x < 0 ? sprout::math::detail::floor_impl(x, -static_cast(static_cast(-x))) - : static_cast(static_cast(x)) + : static_cast(sprout::math::detail::floor_impl(static_cast::type>(x))) +#endif ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler @@ -46,7 +59,7 @@ namespace sprout { } } // namespace detail - using NS_SPROUT_MATH_DETAIL::floor; + using sprout::math::detail::floor; } // namespace math using sprout::math::floor; diff --git a/sprout/math/iceil.hpp b/sprout/math/iceil.hpp index c01a192a..9724613a 100644 --- a/sprout/math/iceil.hpp +++ b/sprout/math/iceil.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #if SPROUT_USE_BUILTIN_CMATH_FUNCTION # include @@ -32,7 +34,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR To iceil(FloatType x) { - return sprout::math::detail::iceil_impl(sprout::ceil(x)); + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : sprout::math::detail::iceil_impl(sprout::math::ceil(x)) + ; } #else template @@ -49,7 +53,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR To iceil(FloatType x) { - return x == 0 ? To(0) + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : x == 0 ? To(0) : std::numeric_limits::max() < x || std::numeric_limits::min() > x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("iceil: large float rounding."), static_cast(x)) : sprout::math::detail::iceil_impl(x, static_cast(x)) diff --git a/sprout/math/ifloor.hpp b/sprout/math/ifloor.hpp index e7e8dd74..4060e48b 100644 --- a/sprout/math/ifloor.hpp +++ b/sprout/math/ifloor.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #if SPROUT_USE_BUILTIN_CMATH_FUNCTION # include @@ -32,7 +34,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR To ifloor(FloatType x) { - return sprout::math::detail::ifloor_impl(sprout::floor(x)); + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : sprout::math::detail::ifloor_impl(sprout::math::floor(x)) + ; } #else template @@ -49,7 +53,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR To ifloor(FloatType x) { - return x == 0 ? To(0) + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : x == 0 ? To(0) : std::numeric_limits::max() < x || std::numeric_limits::min() > x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("ifloor: large float rounding."), static_cast(x)) : sprout::math::detail::ifloor_impl(x, static_cast(x)) diff --git a/sprout/math/iround.hpp b/sprout/math/iround.hpp index 4160a8f4..e769f92b 100644 --- a/sprout/math/iround.hpp +++ b/sprout/math/iround.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #if SPROUT_USE_BUILTIN_CMATH_FUNCTION # include @@ -32,7 +34,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR To iround(FloatType x) { - return sprout::math::detail::iround_impl(sprout::round(x)); + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : sprout::math::detail::iround_impl(sprout::math::round(x)) + ; } #else template @@ -56,7 +60,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR To iround(FloatType x) { - return x == 0 ? To(0) + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : x == 0 ? To(0) : std::numeric_limits::max() < x || std::numeric_limits::min() > x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("iround: large float irounding."), x) : x < 0 ? sprout::math::detail::iround_impl_nagative(x, static_cast(x)) diff --git a/sprout/math/itrunc.hpp b/sprout/math/itrunc.hpp index d0e0f6a4..c4077fa8 100644 --- a/sprout/math/itrunc.hpp +++ b/sprout/math/itrunc.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #if SPROUT_USE_BUILTIN_CMATH_FUNCTION # include @@ -30,7 +32,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR To itrunc(FloatType x) { - return sprout::math::detail::itrunc_impl(sprout::math::trunc(x)); + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : sprout::math::detail::itrunc_impl(sprout::math::trunc(x)) + ; } #else template< @@ -40,7 +44,8 @@ namespace sprout { > inline SPROUT_CONSTEXPR To itrunc(FloatType x) { - return x == 0 ? To(0) + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() + : x == 0 ? To(0) : std::numeric_limits::max() < x || std::numeric_limits::min() > x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("itrunc: large float rounding."), static_cast(x)) : static_cast(x) diff --git a/sprout/math/lgamma.hpp b/sprout/math/lgamma.hpp index f2153b72..d0157fb8 100644 --- a/sprout/math/lgamma.hpp +++ b/sprout/math/lgamma.hpp @@ -187,13 +187,13 @@ namespace sprout { : x <= 0 && sprout::math::is_integer(x) ? std::numeric_limits::infinity() : 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::lgamma(x) -#else +//#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +// : std::lgamma(x) +//#else : x == 1 ? FloatType(0) : x == 2 ? FloatType(0) : static_cast(sprout::math::detail::lgamma_impl(static_cast::type>(x))) -#endif +//#endif ; } diff --git a/sprout/math/llround.hpp b/sprout/math/llround.hpp index 4067e210..bef42ac7 100644 --- a/sprout/math/llround.hpp +++ b/sprout/math/llround.hpp @@ -1,9 +1,12 @@ #ifndef SPROUT_MATH_LLROUND_HPP #define SPROUT_MATH_LLROUND_HPP +#include #include #include #include +#include +#include #include #include @@ -16,20 +19,29 @@ namespace sprout { > inline SPROUT_CONSTEXPR long long llround(FloatType x) { - return sprout::iround(x); + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION + : std::llround(x) +#else + : sprout::math::iround(x); +#endif + ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR long long llround(IntType x) { - return sprout::iround(x); +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION + return std::llround(x); +#else + return sprout::math::iround(x); +#endif } } // namespace detail - using NS_SPROUT_MATH_DETAIL::llround; + using sprout::math::detail::llround; } // namespace math using sprout::math::llround; diff --git a/sprout/math/lround.hpp b/sprout/math/lround.hpp index 559d3a49..71a21e37 100644 --- a/sprout/math/lround.hpp +++ b/sprout/math/lround.hpp @@ -1,9 +1,12 @@ #ifndef SPROUT_MATH_LROUND_HPP #define SPROUT_MATH_LROUND_HPP +#include #include #include #include +#include +#include #include #include @@ -16,20 +19,29 @@ namespace sprout { > inline SPROUT_CONSTEXPR long lround(FloatType x) { - return sprout::iround(x); + return sprout::math::isnan(x) || sprout::math::isinf(x) ? std::numeric_limits::min() +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION + : std::lround(x) +#else + : sprout::math::iround(x); +#endif + ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR long lround(IntType x) { - return sprout::iround(x); +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION + return std::lround(x); +#else + return sprout::math::iround(x); +#endif } } // namespace detail - using NS_SPROUT_MATH_DETAIL::lround; + using sprout::math::detail::lround; } // namespace math using sprout::math::lround; diff --git a/sprout/math/quotient.hpp b/sprout/math/quotient.hpp index 5f2ae673..8fb8db54 100644 --- a/sprout/math/quotient.hpp +++ b/sprout/math/quotient.hpp @@ -24,7 +24,7 @@ namespace sprout { ? std::numeric_limits::quiet_NaN() : x == 0 ? FloatType(0) : y == std::numeric_limits::infinity() || y == -std::numeric_limits::infinity() ? FloatType(0) - : sprout::iround(x / y) + : sprout::math::iround(x / y) ; } diff --git a/sprout/math/remainder.hpp b/sprout/math/remainder.hpp index 9fbbd8ca..af4fd035 100644 --- a/sprout/math/remainder.hpp +++ b/sprout/math/remainder.hpp @@ -23,7 +23,7 @@ namespace sprout { ? std::numeric_limits::quiet_NaN() : x == 0 ? FloatType(0) : y == std::numeric_limits::infinity() || y == -std::numeric_limits::infinity() ? x - : x - sprout::round(x / y) * y + : x - sprout::math::round(x / y) * y ; } diff --git a/sprout/math/round.hpp b/sprout/math/round.hpp index 689a1ec0..83367bd5 100644 --- a/sprout/math/round.hpp +++ b/sprout/math/round.hpp @@ -7,41 +7,54 @@ #include #include #include +#include +#include #include namespace sprout { namespace math { namespace detail { - template - inline SPROUT_CONSTEXPR FloatType - round_impl_positive(FloatType x, FloatType x0) { - return x - x0 < FloatType(0.5) ? x0 - : x0 + 1 + template + inline SPROUT_CONSTEXPR T + round_impl_positive(T x, T x0) { + return x - x0 < T(0.5) ? x0 + : x0 + T(1) ; } - template - inline SPROUT_CONSTEXPR FloatType - round_impl_nagative(FloatType x, FloatType x0) { - return x0 - x < FloatType(0.5) ? x0 - : x0 - 1 + template + inline SPROUT_CONSTEXPR T + round_impl_nagative(T x, T x0) { + return x0 - x < T(0.5) ? x0 + : x0 - T(1) + ; + } + template + inline SPROUT_CONSTEXPR T + round_impl(T x) { + return x < 0 ? sprout::math::detail::round_impl_nagative(x, -static_cast(static_cast(-x))) + : sprout::math::detail::round_impl_positive(x, static_cast(static_cast(x))) ; } + template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType round(FloatType x) { - return x == 0 ? FloatType(0) + 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::round(x) +#else + : x == 0 ? x : std::numeric_limits::max() < x || std::numeric_limits::max() < -x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("round: large float rounding."), x) - : x < 0 ? sprout::math::detail::round_impl_nagative(x, -static_cast(static_cast(-x))) - : sprout::math::detail::round_impl_positive(x, static_cast(static_cast(x))) + : static_cast(sprout::math::detail::round_impl(static_cast::type>(x))) +#endif ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler @@ -52,7 +65,7 @@ namespace sprout { } } // namespace detail - using NS_SPROUT_MATH_DETAIL::round; + using sprout::math::detail::round; } // namespace math using sprout::math::round; diff --git a/sprout/math/tgamma.hpp b/sprout/math/tgamma.hpp index c54c7693..c2f45f48 100644 --- a/sprout/math/tgamma.hpp +++ b/sprout/math/tgamma.hpp @@ -94,7 +94,7 @@ namespace sprout { return sprout::math::detail::tgamma_impl_1( x, sprout::clamp( - sprout::iround(x - T(2)), + sprout::math::iround(x - T(2)), -static_cast(sprout::math::factorial_limit()), static_cast(sprout::math::factorial_limit()) ) diff --git a/sprout/math/trunc.hpp b/sprout/math/trunc.hpp index 41123696..92c7aa7d 100644 --- a/sprout/math/trunc.hpp +++ b/sprout/math/trunc.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -18,16 +19,20 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType trunc(FloatType x) { - return x == 0 ? FloatType(0) + 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::trunc(x) +#else + : x == 0 ? x : std::numeric_limits::max() < x || std::numeric_limits::max() < -x ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::runtime_error("trunc: large float rounding."), x) : x < 0 ? -static_cast(static_cast(-x)) : static_cast(static_cast(x)) +#endif ; } - template< typename IntType, typename sprout::enabler_if::value>::type = sprout::enabler diff --git a/sprout/random/binomial_distribution.hpp b/sprout/random/binomial_distribution.hpp index 78850526..a2526cc1 100644 --- a/sprout/random/binomial_distribution.hpp +++ b/sprout/random/binomial_distribution.hpp @@ -369,7 +369,7 @@ namespace sprout { template SPROUT_CONSTEXPR sprout::random::random_result generate_4(Engine const& eng, RealType v, RealType u, RealType us) const { - return generate_5(eng, v, u, us, static_cast(sprout::floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); + return generate_5(eng, v, u, us, static_cast(sprout::math::floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); } template SPROUT_CONSTEXPR sprout::random::random_result @@ -409,7 +409,7 @@ namespace sprout { SPROUT_CONSTEXPR sprout::random::random_result generate_1_1(Engine const& eng, RealType u) const { return sprout::random::random_result( - static_cast(sprout::floor((2 * btrd_.a / (RealType(0.5) - sprout::abs(u)) + btrd_.b) * u + btrd_.c)), + static_cast(sprout::math::floor((2 * btrd_.a / (RealType(0.5) - sprout::abs(u)) + btrd_.b) * u + btrd_.c)), eng, *this ); } @@ -530,7 +530,7 @@ namespace sprout { template SPROUT_CONSTEXPR sprout::random::random_result generate_4(Engine const& eng, RealType v, RealType u, RealType us) const { - return generate_5(eng, v, u, us, static_cast(sprout::floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); + return generate_5(eng, v, u, us, static_cast(sprout::math::floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); } template SPROUT_CONSTEXPR sprout::random::random_result @@ -557,7 +557,7 @@ namespace sprout { SPROUT_CONSTEXPR sprout::random::random_result generate_1_1(Engine const& eng, RealType u) const { return sprout::random::random_result( - static_cast(sprout::floor((2 * btrd_.a / (RealType(0.5) - sprout::abs(u)) + btrd_.b) * u + btrd_.c)), + static_cast(sprout::math::floor((2 * btrd_.a / (RealType(0.5) - sprout::abs(u)) + btrd_.b) * u + btrd_.c)), eng, *this ); diff --git a/sprout/random/geometric_distribution.hpp b/sprout/random/geometric_distribution.hpp index e1a81d1e..560bd88a 100644 --- a/sprout/random/geometric_distribution.hpp +++ b/sprout/random/geometric_distribution.hpp @@ -83,7 +83,7 @@ namespace sprout { template SPROUT_CONSTEXPR sprout::random::random_result generate_1(Random const& rnd) const { return sprout::random::random_result( - static_cast(sprout::floor(sprout::math::log(RealType(1) - rnd.result()) / log_1mp_)), + static_cast(sprout::math::floor(sprout::math::log(RealType(1) - rnd.result()) / log_1mp_)), rnd.engine(), *this ); diff --git a/sprout/string/float_to_string.hpp b/sprout/string/float_to_string.hpp index 52073d81..572c81b0 100644 --- a/sprout/string/float_to_string.hpp +++ b/sprout/string/float_to_string.hpp @@ -64,7 +64,7 @@ namespace sprout { inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val, bool negative, int digits) { return sprout::detail::float_to_string_impl( - val, negative, digits, static_cast((val - sprout::floor(val)) * sprout::detail::int_pow(sprout::detail::decimal_places_length)), + val, negative, digits, static_cast((val - sprout::math::floor(val)) * sprout::detail::int_pow(sprout::detail::decimal_places_length)), sprout::make_index_tuple::value - 1>::make() ); }