Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorYuri Gorshenin <y@maps.me>2016-03-18 01:43:14 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:56:51 +0300
commit8c4df9033ce9fcc62044900e11a6e9e934869bd4 (patch)
treeb352fc14d49b06aebec2c6562495a972555de72f /base
parentfa8aa617d1d241284d5045deac5947ef4823813a (diff)
[base] Fixed integral to string conversion.
Diffstat (limited to 'base')
-rw-r--r--base/base_tests/string_utils_test.cpp3
-rw-r--r--base/string_utils.hpp20
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);