From 9883dacfe29ff811a3baae5be94db5bcd4e03c5a Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Mon, 5 Aug 2013 22:18:02 +0900 Subject: [PATCH] fix to_string(FloatType): support inf, NaN; bug(digit count) --- sprout/detail/math/float.hpp | 38 ++++++++++---------- sprout/string/float_to_string.hpp | 59 +++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/sprout/detail/math/float.hpp b/sprout/detail/math/float.hpp index 159bb062..b52ede66 100644 --- a/sprout/detail/math/float.hpp +++ b/sprout/detail/math/float.hpp @@ -75,37 +75,37 @@ 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_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) + ? 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 // - template< - typename FloatType, - typename sprout::enabler_if::value>::type = sprout::enabler - > + template inline SPROUT_CONSTEXPR int float_digit_of_impl(FloatType val) { return static_cast((val - sprout::math::floor(val)) * 10); } - template + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > 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)); @@ -114,15 +114,15 @@ namespace sprout { // // float_round_at // - template< - typename FloatType, - typename sprout::enabler_if::value>::type = sprout::enabler - > + template inline SPROUT_CONSTEXPR FloatType float_round_impl(FloatType val, FloatType p10) { return sprout::math::round(val * p10) / p10; } - template + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > inline SPROUT_CONSTEXPR FloatType float_round_at(FloatType val, int digits) { return sprout::detail::float_round_impl(val, sprout::detail::float_pow10(digits)); diff --git a/sprout/string/float_to_string.hpp b/sprout/string/float_to_string.hpp index 572c81b0..092ed4d7 100644 --- a/sprout/string/float_to_string.hpp +++ b/sprout/string/float_to_string.hpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -34,8 +37,9 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl(FloatType val, bool negative, int digits, int v, sprout::index_tuple) { + typedef sprout::basic_string::value> type; return negative - ? sprout::basic_string::value>{ + ? type{ { static_cast('-'), (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) @@ -47,7 +51,7 @@ namespace sprout { }, static_cast(digits + 2 + sprout::detail::decimal_places_length) } - : sprout::basic_string::value>{ + : type{ { (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) : Indexes == digits ? static_cast('.') @@ -79,11 +83,19 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val) { - return sprout::detail::float_to_string( - sprout::detail::float_round_at(val < 0 ? -val : val, sprout::detail::decimal_places_length), - val < 0, - sprout::detail::float_digits(val) - ); + typedef sprout::basic_string::value> type; + return sprout::math::isinf(val) ? sprout::math::signbit(val) + ? type{{static_cast('-'), static_cast('i'), static_cast('n'), static_cast('f')}, 4} + : type{{static_cast('i'), static_cast('n'), static_cast('f')}, 3} + : sprout::math::isnan(val) ? sprout::math::signbit(val) + ? type{{static_cast('-'), static_cast('n'), static_cast('a'), static_cast('n')}, 4} + : type{{static_cast('n'), static_cast('a'), static_cast('n')}, 3} + : 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) + ) + ; } namespace detail { @@ -111,8 +123,9 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_exp(FloatType val, bool negative, int exponent10, int e10_digits, sprout::index_tuple) { + typedef sprout::basic_string::value> type; return negative - ? sprout::basic_string::value>{ + ? type{ { static_cast('-'), (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) @@ -128,7 +141,7 @@ namespace sprout { }, static_cast(5 + sprout::detail::decimal_places_length + e10_digits) } - : sprout::basic_string::value>{ + : type{ { (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) : Indexes == 1 ? static_cast('.') @@ -156,16 +169,24 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_exp(FloatType val) { - return sprout::detail::float_to_string_exp( - sprout::detail::float_round_at( - (val < 0 ? -val : val) / sprout::detail::float_pow10(sprout::detail::float_exponent10(val)), - sprout::detail::decimal_places_length - ), - val < 0, - sprout::detail::float_exponent10(val), - NS_SSCRISK_CEL_OR_SPROUT::max(sprout::detail::int_digits(sprout::detail::float_exponent10(val)), 2), - sprout::make_index_tuple::value - 1>::make() - ); + typedef sprout::basic_string::value> type; + return sprout::math::isinf(val) ? sprout::math::signbit(val) + ? type{{static_cast('-'), static_cast('i'), static_cast('n'), static_cast('f')}, 4} + : type{{static_cast('i'), static_cast('n'), static_cast('f')}, 3} + : sprout::math::isnan(val) ? sprout::math::signbit(val) + ? type{{static_cast('-'), static_cast('n'), static_cast('a'), static_cast('n')}, 4} + : type{{static_cast('n'), static_cast('a'), static_cast('n')}, 3} + : sprout::detail::float_to_string_exp( + sprout::detail::float_round_at( + (val < 0 ? -val : val) / sprout::detail::float_pow10(sprout::detail::float_exponent10(val)), + sprout::detail::decimal_places_length + ), + sprout::math::signbit(val), + sprout::detail::float_exponent10(val), + NS_SSCRISK_CEL_OR_SPROUT::max(sprout::detail::int_digits(sprout::detail::float_exponent10(val)), 2), + sprout::make_index_tuple::value - 1>::make() + ) + ; } //