diff --git a/sprout/cmath.hpp b/sprout/cmath.hpp index 9791dc11..eeaf2814 100644 --- a/sprout/cmath.hpp +++ b/sprout/cmath.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/math/exp.hpp b/sprout/math/exp.hpp index 7d8cf21f..1468a38d 100644 --- a/sprout/math/exp.hpp +++ b/sprout/math/exp.hpp @@ -34,8 +34,8 @@ namespace sprout { inline SPROUT_CONSTEXPR FloatType exp(FloatType x) { typedef double type; - return !(x > -1) ? 1 / sprout::math::detail::exp_impl(-static_cast(x)) - : sprout::math::detail::exp_impl(static_cast(x)) + return !(x > -1) ? static_cast(1 / sprout::math::detail::exp_impl(-static_cast(x))) + : static_cast(sprout::math::detail::exp_impl(static_cast(x))) ; } diff --git a/sprout/math/exponential.hpp b/sprout/math/exponential.hpp index 54c9e7a4..95602a4f 100644 --- a/sprout/math/exponential.hpp +++ b/sprout/math/exponential.hpp @@ -10,8 +10,5 @@ #include #include #include -#include -#include -#include #endif // #ifndef SPROUT_MATH_EXPONENTIAL_HPP diff --git a/sprout/math/floating_point.hpp b/sprout/math/floating_point.hpp new file mode 100644 index 00000000..72e97d35 --- /dev/null +++ b/sprout/math/floating_point.hpp @@ -0,0 +1,11 @@ +#ifndef SPROUT_MATH_FLOATING_POINT_HPP +#define SPROUT_MATH_FLOATING_POINT_HPP + +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_MATH_FLOATING_POINT_HPP diff --git a/sprout/math/functions.hpp b/sprout/math/functions.hpp index 6d1cb184..e73c3cdd 100644 --- a/sprout/math/functions.hpp +++ b/sprout/math/functions.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/math/ilogb.hpp b/sprout/math/ilogb.hpp new file mode 100644 index 00000000..a58ccc5d --- /dev/null +++ b/sprout/math/ilogb.hpp @@ -0,0 +1,47 @@ +#ifndef SPROUT_MATH_ILOGB_HPP +#define SPROUT_MATH_ILOGB_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR int + ilogb(FloatType x) { + return sprout::math::iszero(x) ? FP_ILOGB0 + : sprout::math::isinf(x) ? INT_MAX + : sprout::math::isnan(x) ? FP_ILOGBNAN + : static_cast(sprout::math::logb(x)) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR int + ilogb(IntType x) { + return sprout::math::detail::ilogb(static_cast(x)); + } + } // namespace detail + + using NS_SPROUT_MATH_DETAIL::ilogb; + } // namespace math + + using sprout::math::ilogb; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_ILOGB_HPP diff --git a/sprout/math/ldexp.hpp b/sprout/math/ldexp.hpp index 55c31fcd..8029f30a 100644 --- a/sprout/math/ldexp.hpp +++ b/sprout/math/ldexp.hpp @@ -16,7 +16,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType ldexp(FloatType x, int exp) { - return static_cast(x * sprout::detail::pow_n(FloatType(2), exp)); + return x * sprout::detail::pow_n(FloatType(2), exp); } template< diff --git a/sprout/math/log2.hpp b/sprout/math/log2.hpp index 59770748..385e2921 100644 --- a/sprout/math/log2.hpp +++ b/sprout/math/log2.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_MATH_LOG2HPP -#define SPROUT_MATH_LOG2HPP +#ifndef SPROUT_MATH_LOG2_HPP +#define SPROUT_MATH_LOG2_HPP #include #include @@ -36,4 +36,4 @@ namespace sprout { using sprout::math::log2; } // namespace sprout -#endif // #ifndef SPROUT_MATH_LOG2HPP +#endif // #ifndef SPROUT_MATH_LOG2_HPP diff --git a/sprout/math/log_a.hpp b/sprout/math/log_a.hpp new file mode 100644 index 00000000..8de92409 --- /dev/null +++ b/sprout/math/log_a.hpp @@ -0,0 +1,47 @@ +#ifndef SPROUT_MATH_LOG_A_HPP +#define SPROUT_MATH_LOG_A_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + log_a(FloatType x, FloatType y) { + return x == 2 ? sprout::math::log(y) / sprout::math::ln_two() + : x == 10 ? sprout::math::log(y) / sprout::math::ln_ten() + : sprout::math::log(y) / sprout::math::log(x) + ; + } + + template< + typename ArithmeticType1, + typename ArithmeticType2, + typename sprout::enabler_if< + std::is_arithmetic::value && std::is_arithmetic::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::float_promote::type + log_a(ArithmeticType1 x, ArithmeticType2 y) { + typedef typename sprout::float_promote::type type; + return sprout::math::detail::log_a(static_cast(x), static_cast(y)); + } + } // namespace detail + + using sprout::math::detail::log_a; + } // namespace math + + using sprout::math::log_a; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_LOG_A_HPP diff --git a/sprout/math/logb.hpp b/sprout/math/logb.hpp new file mode 100644 index 00000000..c8541728 --- /dev/null +++ b/sprout/math/logb.hpp @@ -0,0 +1,102 @@ +#ifndef SPROUT_MATH_LOGB_HPP +#define SPROUT_MATH_LOGB_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR T + logb_impl_2_neg_lo(T x, T x0, T base, T exp) { + return base < 1 ? sprout::math::detail::logb_impl_2_neg_lo(x, x0 * FLT_RADIX, x / (x0 / FLT_RADIX), exp - 1) + : exp + ; + } + template + inline SPROUT_CONSTEXPR T + logb_impl_2_neg_hi(T x, T x0, T base, T exp) { + return !(base < FLT_RADIX) ? sprout::math::detail::logb_impl_2_neg_hi(x, x0 / FLT_RADIX, x / (x0 * FLT_RADIX), exp + 1) + : exp + ; + } + template + inline SPROUT_CONSTEXPR T + logb_impl_2_pos_lo(T x, T x0, T base, T exp) { + return base < 1 ? sprout::math::detail::logb_impl_2_pos_lo(x, x0 * FLT_RADIX, x / (x0 / FLT_RADIX), exp + 1) + : exp + ; + } + template + inline SPROUT_CONSTEXPR T + logb_impl_2_pos_hi(T x, T x0, T base, T exp) { + return !(base < FLT_RADIX) ? sprout::math::detail::logb_impl_2_pos_hi(x, x0 / FLT_RADIX, x / (x0 * FLT_RADIX), exp - 1) + : exp + ; + } + template + inline SPROUT_CONSTEXPR T + logb_impl_2(T x, T x0, T base, T exp) { + return exp < 0 + ? base < 1 ? sprout::math::detail::logb_impl_2_neg_lo(x, x0 * FLT_RADIX, x / (x0 / FLT_RADIX), exp - 1) + : !(base < FLT_RADIX) ? sprout::math::detail::logb_impl_2_neg_hi(x, x0 / FLT_RADIX, x / (x0 * FLT_RADIX), exp + 1) + : exp + : base < 1 ? sprout::math::detail::logb_impl_2_pos_lo(x, x0 * FLT_RADIX, x / (x0 / FLT_RADIX), exp + 1) + : !(base < FLT_RADIX) ? sprout::math::detail::logb_impl_2_pos_hi(x, x0 / FLT_RADIX, x / (x0 * FLT_RADIX), exp - 1) + : exp + ; + } + template + inline SPROUT_CONSTEXPR T + logb_impl_1(T x, T x0, T exp) { + return sprout::math::detail::logb_impl_2(x, x0, x / x0, exp); + } + template + inline SPROUT_CONSTEXPR T + logb_impl(T x, T exp) { + return std::numeric_limits::max() < exp || std::numeric_limits::min() > exp + ? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("trunc: large float rounding."), exp) + : sprout::math::detail::logb_impl_1( + x, sprout::detail::pow_n(T(FLT_RADIX), static_cast(exp)), + static_cast(static_cast(exp)) + ) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + logb(FloatType x) { + return x < 0 ? sprout::math::detail::logb_impl(-x, sprout::math::trunc(sprout::math::log_a(FloatType(FLT_RADIX), -x))) + : sprout::math::detail::logb_impl(x, sprout::math::trunc(sprout::math::log_a(FloatType(FLT_RADIX), x))) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + logb(IntType x) { + return sprout::math::detail::logb(static_cast(x)); + } + } // namespace detail + + using NS_SPROUT_MATH_DETAIL::logb; + } // namespace math + + using sprout::math::logb; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_LOGB_HPP diff --git a/sprout/math/power.hpp b/sprout/math/power.hpp index 2c45a2b5..21219308 100644 --- a/sprout/math/power.hpp +++ b/sprout/math/power.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #endif // #ifndef SPROUT_MATH_POWER_HPP diff --git a/sprout/math/scalbln.hpp b/sprout/math/scalbln.hpp index 7f30a3d9..0d5f9acb 100644 --- a/sprout/math/scalbln.hpp +++ b/sprout/math/scalbln.hpp @@ -17,7 +17,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType scalbln(FloatType x, long exp) { - return static_cast(x * sprout::detail::pow_n(FloatType(FLT_RADIX), exp)); + return x * sprout::detail::pow_n(FloatType(FLT_RADIX), exp); } template< diff --git a/sprout/math/scalbn.hpp b/sprout/math/scalbn.hpp index f56737ca..f2d0533e 100644 --- a/sprout/math/scalbn.hpp +++ b/sprout/math/scalbn.hpp @@ -17,7 +17,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType scalbn(FloatType x, int exp) { - return static_cast(x * sprout::detail::pow_n(FloatType(FLT_RADIX), exp)); + return x * sprout::detail::pow_n(FloatType(FLT_RADIX), exp); } template<