#ifndef SPROUT_DETAIL_FLOAT_HPP #define SPROUT_DETAIL_FLOAT_HPP #include #include #include #include #include #include namespace sprout { namespace detail { // // float_pow10 // template inline SPROUT_CONSTEXPR FloatType float_pow10_positive(int exponent) { return exponent ? sprout::detail::float_pow10_positive(exponent - 1) * 10 : FloatType(1) ; } template inline SPROUT_CONSTEXPR FloatType float_pow10_negative(int exponent) { return exponent ? sprout::detail::float_pow10_negative(exponent + 1) / 10 : FloatType(1) ; } template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType float_pow10(int exponent) { return exponent < 0 ? sprout::detail::float_pow10_negative(exponent) : sprout::detail::float_pow10_positive(exponent) ; } // // float_exponent10 // template inline SPROUT_CONSTEXPR int float_exponent10_positive(FloatType val) { return val < 10 ? 0 : 1 + sprout::detail::float_exponent10_positive(val / 10) ; } template inline SPROUT_CONSTEXPR int float_exponent10_negative(FloatType val) { return val < 1 ? 1 + sprout::detail::float_exponent10_negative(val * 10) : 0 ; } template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR int float_exponent10(FloatType val) { return val < 0 ? val > -1 ? sprout::detail::float_exponent10_negative(-val) : sprout::detail::float_exponent10_positive(-val) : val < 1 ? sprout::detail::float_exponent10_negative(val) : sprout::detail::float_exponent10_positive(val) ; } // // float_digits // template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR int float_digits_impl(FloatType val) { return val < 1 ? 0 : 1 + sprout::detail::float_digits_impl(val / 10) ; } template inline SPROUT_CONSTEXPR int float_digits(FloatType val) { return val < 0 ? val > -1 ? 1 : 1 + sprout::detail::float_digits_impl(-val / 10) : val < 1 ? 1 : 1 + sprout::detail::float_digits_impl(val / 10) ; } // // float_digit_at // template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR int float_digit_of_impl(FloatType val) { return static_cast((val - sprout::math::floor(val)) * 10); } template inline SPROUT_CONSTEXPR int float_digit_at(FloatType val, int digits) { return sprout::detail::float_digit_of_impl(val / sprout::detail::float_pow10(digits + 1)); } // // float_round_at // template< typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR FloatType float_round_impl(FloatType val, FloatType p10) { return sprout::math::round(val * p10) / p10; } template inline SPROUT_CONSTEXPR FloatType float_round_at(FloatType val, int digits) { return sprout::detail::float_round_impl(val, sprout::detail::float_pow10(digits)); } } // namespace detail } // namespace sprout #endif // #ifndef SPROUT_DETAIL_FLOAT_HPP