From be0bc155d8ee60361aba268dc4f1d06b553b8560 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 31 Dec 2013 21:26:22 +0900 Subject: [PATCH] fix float_exponent10 order O(logN) --- sprout/darkroom/renderers/calculate.hpp | 2 +- sprout/detail/math/float.hpp | 80 +++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/sprout/darkroom/renderers/calculate.hpp b/sprout/darkroom/renderers/calculate.hpp index 7f65dd26..6021c219 100644 --- a/sprout/darkroom/renderers/calculate.hpp +++ b/sprout/darkroom/renderers/calculate.hpp @@ -16,7 +16,7 @@ namespace sprout { namespace darkroom { namespace renderers { // - // + // default_depth // SPROUT_STATIC_CONSTEXPR std::size_t default_depth = 4; diff --git a/sprout/detail/math/float.hpp b/sprout/detail/math/float.hpp index c5d9673c..50914d9a 100644 --- a/sprout/detail/math/float.hpp +++ b/sprout/detail/math/float.hpp @@ -34,21 +34,89 @@ namespace sprout { // // float_exponent10 // - // !!! TODO: O(logN) + template + inline SPROUT_CONSTEXPR sprout::pair + float_exponent10_positive_1(sprout::pair const& current, int n) { + typedef sprout::pair type; + return (current.second) < 10 ? current + : n == 1 ? type(current.first + 1, current.second / 10) + : sprout::detail::float_exponent10_positive_1( + sprout::detail::float_exponent10_positive_1( + current, + n / 2 + ), + n - n / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + float_exponent10_positive_0(sprout::pair const& current, int n) { + return (current.second) < 10 ? current + : sprout::detail::float_exponent10_positive_0( + sprout::detail::float_exponent10_positive_1( + current, + n + ), + n * 2 + ) + ; + } template inline SPROUT_CONSTEXPR int float_exponent10_positive(FloatType val) { - return val < 10 ? 0 - : 1 + sprout::detail::float_exponent10_positive(val / 10) + typedef sprout::pair type; + return float_exponent10_positive_0(type(val, 0), 1).first; + } + template + inline SPROUT_CONSTEXPR sprout::pair + float_exponent10_negative_1(sprout::pair const& current, int n) { + typedef sprout::pair type; + return !((current.second) < 1) ? current + : n == 1 ? type(current.first + 1, current.second * 10) + : sprout::detail::float_exponent10_negative_1( + sprout::detail::float_exponent10_negative_1( + current, + n / 2 + ), + n - n / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + float_exponent10_negative_0(sprout::pair const& current, int n) { + return !((current.second) < 1) ? current + : sprout::detail::float_exponent10_negative_0( + sprout::detail::float_exponent10_negative_1( + current, + n + ), + n * 2 + ) ; } template inline SPROUT_CONSTEXPR int float_exponent10_negative(FloatType val) { - return val < 1 ? 1 + sprout::detail::float_exponent10_negative(val * 10) - : 0 - ; + typedef sprout::pair type; + return float_exponent10_negative_0(type(val, 0), 1).first; } + // !!! OLD: +// 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