diff --git a/sprout/math/ceil.hpp b/sprout/math/ceil.hpp index 26b914e7..f2fe790c 100644 --- a/sprout/math/ceil.hpp +++ b/sprout/math/ceil.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -15,8 +16,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR FloatType ceil_impl(FloatType x, FloatType x0) { - return x - x0 < std::numeric_limits::epsilon() - ? x0 + return x - x0 < std::numeric_limits::epsilon() ? x0 : x0 + 1 ; } @@ -26,11 +26,11 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType ceil(FloatType x) { - return std::numeric_limits::max() < x || std::numeric_limits::max() < -x - ? throw std::domain_error("ceil: Sorry, not implemented.") - : x < 0 - ? -static_cast(static_cast(-x)) - : sprout::math::detail::ceil_impl(x, static_cast(static_cast(x))) + return sprout::math::isinf(x) ? x + : std::numeric_limits::max() < x || std::numeric_limits::max() < -x + ? throw std::domain_error("ceil: Sorry, not implemented.") + : x < 0 ? -static_cast(static_cast(-x)) + : sprout::math::detail::ceil_impl(x, static_cast(static_cast(x))) ; } diff --git a/sprout/math/floor.hpp b/sprout/math/floor.hpp index 1267e2ef..6f8e24e1 100644 --- a/sprout/math/floor.hpp +++ b/sprout/math/floor.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -15,8 +16,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR FloatType floor_impl(FloatType x, FloatType x0) { - return x0 - x < std::numeric_limits::epsilon() - ? x0 + return x0 - x < std::numeric_limits::epsilon() ? x0 : x0 - 1 ; } @@ -26,11 +26,11 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType floor(FloatType x) { - return std::numeric_limits::max() < x || std::numeric_limits::max() < -x - ? throw std::domain_error("floor: Sorry, not implemented.") - : x < 0 - ? sprout::math::detail::floor_impl(x, -static_cast(static_cast(-x))) - : static_cast(static_cast(x)) + return sprout::math::isinf(x) ? x + : std::numeric_limits::max() < x || std::numeric_limits::max() < -x + ? throw std::domain_error("floor: Sorry, not implemented.") + : x < 0 ? sprout::math::detail::floor_impl(x, -static_cast(static_cast(-x))) + : static_cast(static_cast(x)) ; } diff --git a/sprout/math/llround.hpp b/sprout/math/llround.hpp new file mode 100644 index 00000000..fc92734b --- /dev/null +++ b/sprout/math/llround.hpp @@ -0,0 +1,55 @@ +#ifndef SPROUT_MATH_LLROUND_HPP +#define SPROUT_MATH_LLROUND_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR long long + llround_impl_positive(FloatType x, long long x0) { + return x - x0 < FloatType(0.5) ? x0 + : x0 + 1 + ; + } + template + inline SPROUT_CONSTEXPR long long + llround_impl_nagative(FloatType x, long long x0) { + return x0 - x < FloatType(0.5) ? x0 + : x0 - 1 + ; + } + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR long long + llround(FloatType x) { + return x < 0 ? sprout::math::detail::llround_impl_nagative(x, static_cast(x)) + : sprout::math::detail::llround_impl_positive(x, static_cast(x)) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR long long + llround(IntType x) { + return static_cast(x); + } + } // namespacedetailmath + + using NS_SPROUT_MATH_DETAIL::llround; + } // namespace math + + using sprout::math::llround; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_LLROUND_HPP diff --git a/sprout/math/lround.hpp b/sprout/math/lround.hpp new file mode 100644 index 00000000..a9528a14 --- /dev/null +++ b/sprout/math/lround.hpp @@ -0,0 +1,55 @@ +#ifndef SPROUT_MATH_LROUND_HPP +#define SPROUT_MATH_LROUND_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR long + lround_impl_positive(FloatType x, long x0) { + return x - x0 < FloatType(0.5) ? x0 + : x0 + 1 + ; + } + template + inline SPROUT_CONSTEXPR long + lround_impl_nagative(FloatType x, long x0) { + return x0 - x < FloatType(0.5) ? x0 + : x0 - 1 + ; + } + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR long + lround(FloatType x) { + return x < 0 ? sprout::math::detail::lround_impl_nagative(x, static_cast(x)) + : sprout::math::detail::lround_impl_positive(x, static_cast(x)) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR long + lround(IntType x) { + return static_cast(x); + } + } // namespacedetailmath + + using NS_SPROUT_MATH_DETAIL::lround; + } // namespace math + + using sprout::math::lround; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_LROUND_HPP diff --git a/sprout/math/nearest.hpp b/sprout/math/nearest.hpp index 9ac91dde..15dffcd9 100644 --- a/sprout/math/nearest.hpp +++ b/sprout/math/nearest.hpp @@ -6,5 +6,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_MATH_NEAREST_HPP diff --git a/sprout/math/round.hpp b/sprout/math/round.hpp index f981e5c5..aa5eb84b 100644 --- a/sprout/math/round.hpp +++ b/sprout/math/round.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -15,16 +16,14 @@ namespace sprout { template inline SPROUT_CONSTEXPR FloatType round_impl_positive(FloatType x, FloatType x0) { - return x - x0 < FloatType(0.5) - ? x0 + return x - x0 < FloatType(0.5) ? x0 : x0 + 1 ; } template inline SPROUT_CONSTEXPR FloatType round_impl_nagative(FloatType x, FloatType x0) { - return x0 - x < FloatType(0.5) - ? x0 + return x0 - x < FloatType(0.5) ? x0 : x0 - 1 ; } @@ -34,11 +33,11 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType round(FloatType x) { - return std::numeric_limits::max() < x || std::numeric_limits::max() < -x - ? throw std::domain_error("round: Sorry, not implemented.") - : 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))) + return sprout::math::isinf(x) ? x + : std::numeric_limits::max() < x || std::numeric_limits::max() < -x + ? throw std::domain_error("round: Sorry, not implemented.") + : 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))) ; } diff --git a/sprout/math/trunc.hpp b/sprout/math/trunc.hpp index 99d3ac98..9334f703 100644 --- a/sprout/math/trunc.hpp +++ b/sprout/math/trunc.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -18,11 +19,11 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType trunc(FloatType x) { - return std::numeric_limits::max() < x || std::numeric_limits::max() < -x - ? throw std::domain_error("trunc: Sorry, not implemented.") - : x < 0 - ? -static_cast(static_cast(-x)) - : static_cast(static_cast(x)) + return sprout::math::isinf(x) ? x + : std::numeric_limits::max() < x || std::numeric_limits::max() < -x + ? throw std::domain_error("trunc: Sorry, not implemented.") + : x < 0 ? -static_cast(static_cast(-x)) + : static_cast(static_cast(x)) ; }