From fc5e510c3c99ee74a7fc79f5699996272ee92223 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 6 Aug 2013 00:05:45 +0900 Subject: [PATCH] fix to_string(FloatType): for large float value --- sprout/detail/math/float.hpp | 106 +++++++++++++++++++----------- sprout/string/float_to_string.hpp | 2 +- 2 files changed, 67 insertions(+), 41 deletions(-) diff --git a/sprout/detail/math/float.hpp b/sprout/detail/math/float.hpp index b52ede66..a7963b0f 100644 --- a/sprout/detail/math/float.hpp +++ b/sprout/detail/math/float.hpp @@ -7,41 +7,26 @@ #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) - ; + return sprout::detail::pow_n(FloatType(10), exponent); } // // float_exponent10 // + // !!! template inline SPROUT_CONSTEXPR int float_exponent10_positive(FloatType val) { @@ -72,28 +57,6 @@ namespace sprout { ; } - // - // float_digits - // - template - inline SPROUT_CONSTEXPR int - float_digits_impl(FloatType val, FloatType n) { - return val / n < 1 ? 0 - : 1 + sprout::detail::float_digits_impl(val, n * FloatType(10)) - ; - } - template< - typename FloatType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR int - float_digits(FloatType val) { - return val < 0 - ? val > -1 ? 1 : 1 + sprout::detail::float_digits_impl(-val, FloatType(10)) - : val < 1 ? 1 : 1 + sprout::detail::float_digits_impl(val, FloatType(10)) - ; - } - // // float_digit_at // @@ -111,6 +74,69 @@ namespace sprout { return sprout::detail::float_digit_of_impl(val / sprout::detail::float_pow10(digits + 1)); } + // + // float_digits + // + template + inline SPROUT_CONSTEXPR sprout::pair + float_digits_impl_1(sprout::pair const& current, FloatType val, int n) { + typedef sprout::pair type; + return (val / current.second) < 1 ? current + : n == 1 ? type(current.first + 1, current.second * FloatType(10)) + : sprout::detail::float_digits_impl_1( + sprout::detail::float_digits_impl_1( + current, + val, n / 2 + ), + val, n - n / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + float_digits_impl(sprout::pair const& current, FloatType val, int n) { + return (val / current.second) < 1 ? current + : sprout::detail::float_digits_impl( + sprout::detail::float_digits_impl_1( + current, + val, n + ), + val, n * 2 + ) + ; + } + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR int + float_digits(FloatType val) { + typedef sprout::pair type; + return val < 0 + ? val > -1 ? 1 : sprout::detail::float_digits_impl(type(1, FloatType(10)), -val, 1).first + : val < 1 ? 1 : sprout::detail::float_digits_impl(type(1, FloatType(10)), val, 1).first + ; + } + + // + // float_digits_checked + // + template + inline SPROUT_CONSTEXPR int + float_digits_checked_impl(FloatType val, int digits) { + return val == 0 ? digits + : sprout::detail::float_digit_at(val, digits - 1) == 0 ? digits - 1 : digits + ; + } + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR int + float_digits_checked(FloatType val) { + return sprout::detail::float_digits_checked_impl(val, sprout::detail::float_digits(val)); + } + // // float_round_at // diff --git a/sprout/string/float_to_string.hpp b/sprout/string/float_to_string.hpp index 092ed4d7..e03563bb 100644 --- a/sprout/string/float_to_string.hpp +++ b/sprout/string/float_to_string.hpp @@ -93,7 +93,7 @@ namespace sprout { : sprout::detail::float_to_string( sprout::detail::float_round_at(val < 0 ? -val : val, sprout::detail::decimal_places_length), sprout::math::signbit(val), - sprout::detail::float_digits(val) + sprout::detail::float_digits_checked(val) ) ; }