diff options
author | Yuri Gorshenin <y@maps.me> | 2016-03-18 01:43:14 +0300 |
---|---|---|
committer | Sergey Yershov <yershov@corp.mail.ru> | 2016-03-23 16:56:51 +0300 |
commit | 8c4df9033ce9fcc62044900e11a6e9e934869bd4 (patch) | |
tree | b352fc14d49b06aebec2c6562495a972555de72f /base | |
parent | fa8aa617d1d241284d5045deac5947ef4823813a (diff) |
[base] Fixed integral to string conversion.
Diffstat (limited to 'base')
-rw-r--r-- | base/base_tests/string_utils_test.cpp | 3 | ||||
-rw-r--r-- | base/string_utils.hpp | 20 |
2 files changed, 21 insertions, 2 deletions
diff --git a/base/base_tests/string_utils_test.cpp b/base/base_tests/string_utils_test.cpp index 3f6dc94418..55b256bacf 100644 --- a/base/base_tests/string_utils_test.cpp +++ b/base/base_tests/string_utils_test.cpp @@ -253,6 +253,9 @@ UNIT_TEST(to_string) TEST_EQUAL(strings::to_string(123456789123456789ULL), "123456789123456789", ()); TEST_EQUAL(strings::to_string(-987654321987654321LL), "-987654321987654321", ()); + + uint64_t const n = numeric_limits<uint64_t>::max(); + TEST_EQUAL(strings::to_string(n), "18446744073709551615", ()); } UNIT_TEST(to_string_dac) diff --git a/base/string_utils.hpp b/base/string_utils.hpp index 09f459d90c..4d006a0d08 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -223,6 +223,22 @@ template <typename T> string to_string(T t) namespace impl { +template <typename T> +int UpperBoundOnChars() +{ + // It's wrong to return just numeric_limits<T>::digits10 + [is + // signed] because digits10 for a type T is computed as: + // + // floor(log10(2 ^ (CHAR_BITS * sizeof(T)))) = + // floor(CHAR_BITS * sizeof(T) * log10(2)) + // + // Therefore, due to rounding, we need to compensate possible + // error. + // + // NOTE: following code works only on two-complement systems! + + return numeric_limits<T>::digits10 + is_signed<T>::value + 1; +} template <typename T> char * to_string_digits(char * buf, T i) { @@ -238,7 +254,7 @@ template <typename T> char * to_string_digits(char * buf, T i) template <typename T> string to_string_signed(T i) { bool const negative = i < 0; - int const sz = numeric_limits<T>::digits10 + 1; + int const sz = UpperBoundOnChars<T>(); char buf[sz]; char * end = buf + sz; char * beg = to_string_digits(end, negative ? -i : i); @@ -252,7 +268,7 @@ template <typename T> string to_string_signed(T i) template <typename T> string to_string_unsigned(T i) { - int const sz = numeric_limits<T>::digits10; + int const sz = UpperBoundOnChars<T>(); char buf[sz]; char * end = buf + sz; char * beg = to_string_digits(end, i); |