| # Libchrome does not support/require dmg_fp library. Instead, use standard |
| # library. |
| |
| --- a/base/strings/string_number_conversions.cc |
| +++ b/base/strings/string_number_conversions.cc |
| @@ -16,7 +16,6 @@ |
| #include "base/numerics/safe_math.h" |
| #include "base/scoped_clear_errno.h" |
| #include "base/strings/utf_string_conversions.h" |
| -#include "base/third_party/dmg_fp/dmg_fp.h" |
| |
| namespace base { |
| |
| @@ -361,20 +360,35 @@ string16 NumberToString16(unsigned long long value) { |
| } |
| |
| std::string NumberToString(double value) { |
| - // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. |
| - char buffer[32]; |
| - dmg_fp::g_fmt(buffer, value); |
| - return std::string(buffer); |
| + auto ret = std::to_string(value); |
| + // If this returned an integer, don't do anything. |
| + if (ret.find('.') == std::string::npos) { |
| + return ret; |
| + } |
| + // Otherwise, it has an annoying tendency to leave trailing zeros. |
| + size_t len = ret.size(); |
| + while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') { |
| + --len; |
| + } |
| + ret.erase(len); |
| + return ret; |
| } |
| |
| base::string16 NumberToString16(double value) { |
| - // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. |
| - char buffer[32]; |
| - dmg_fp::g_fmt(buffer, value); |
| + auto tmp = std::to_string(value); |
| + base::string16 ret(tmp.c_str(), tmp.c_str() + tmp.length()); |
| |
| - // The number will be ASCII. This creates the string using the "input |
| - // iterator" variant which promotes from 8-bit to 16-bit via "=". |
| - return base::string16(&buffer[0], &buffer[strlen(buffer)]); |
| + // If this returned an integer, don't do anything. |
| + if (ret.find('.') == std::string::npos) { |
| + return ret; |
| + } |
| + // Otherwise, it has an annoying tendency to leave trailing zeros. |
| + size_t len = ret.size(); |
| + while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') { |
| + --len; |
| + } |
| + ret.erase(len); |
| + return ret; |
| } |
| |
| bool StringToInt(StringPiece input, int* output) { |
| @@ -418,14 +432,10 @@ bool StringToSizeT(StringPiece16 input, size_t* output) { |
| } |
| |
| bool StringToDouble(const std::string& input, double* output) { |
| - // Thread-safe? It is on at least Mac, Linux, and Windows. |
| - ScopedClearErrno clear_errno; |
| - |
| char* endptr = nullptr; |
| - *output = dmg_fp::strtod(input.c_str(), &endptr); |
| + *output = strtod(input.c_str(), &endptr); |
| |
| // Cases to return false: |
| - // - If errno is ERANGE, there was an overflow or underflow. |
| // - If the input string is empty, there was nothing to parse. |
| // - If endptr does not point to the end of the string, there are either |
| // characters remaining in the string after a parsed number, or the string |
| @@ -433,10 +443,11 @@ bool StringToDouble(const std::string& input, double* output) { |
| // expected end given the string's stated length to correctly catch cases |
| // where the string contains embedded NUL characters. |
| // - If the first character is a space, there was leading whitespace |
| - return errno == 0 && |
| - !input.empty() && |
| + return !input.empty() && |
| input.c_str() + input.length() == endptr && |
| - !isspace(input[0]); |
| + !isspace(input[0]) && |
| + *output != std::numeric_limits<double>::infinity() && |
| + *output != -std::numeric_limits<double>::infinity(); |
| } |
| |
| // Note: if you need to add String16ToDouble, first ask yourself if it's |
| --- a/base/strings/string_number_conversions_unittest.cc |
| +++ b/base/strings/string_number_conversions_unittest.cc |
| @@ -754,20 +754,8 @@ TEST(StringNumberConversionsTest, StringToDouble) { |
| {"9e999", HUGE_VAL, false}, |
| {"9e1999", HUGE_VAL, false}, |
| {"9e19999", HUGE_VAL, false}, |
| - {"9e99999999999999999999", HUGE_VAL, false}, |
| - {"-9e307", -9e307, true}, |
| - {"-1.7976e308", -1.7976e308, true}, |
| - {"-1.7977e308", -HUGE_VAL, false}, |
| - {"-1.797693134862315807e+308", -HUGE_VAL, true}, |
| - {"-1.797693134862315808e+308", -HUGE_VAL, false}, |
| - {"-9e308", -HUGE_VAL, false}, |
| - {"-9e309", -HUGE_VAL, false}, |
| - {"-9e999", -HUGE_VAL, false}, |
| - {"-9e1999", -HUGE_VAL, false}, |
| - {"-9e19999", -HUGE_VAL, false}, |
| - {"-9e99999999999999999999", -HUGE_VAL, false}, |
| - |
| - // Test more exponents. |
| + {"9e99999999999999999999", std::numeric_limits<double>::infinity(), false}, |
| + {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(), false}, |
| {"1e-2", 0.01, true}, |
| {"42 ", 42.0, false}, |
| {" 1e-2", 0.01, false}, |
| @@ -797,7 +785,8 @@ TEST(StringNumberConversionsTest, StringToDouble) { |
| for (size_t i = 0; i < arraysize(cases); ++i) { |
| double output; |
| errno = 1; |
| - EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)); |
| + EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)) |
| + << "for input=" << cases[i].input << "got output=" << output; |
| if (cases[i].success) |
| EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged. |
| EXPECT_DOUBLE_EQ(cases[i].output, output); |
| @@ -818,13 +807,13 @@ TEST(StringNumberConversionsTest, DoubleToString) { |
| double input; |
| const char* expected; |
| } cases[] = { |
| - {0.0, "0"}, |
| + {0.0, "0.0"}, |
| {1.25, "1.25"}, |
| - {1.33518e+012, "1.33518e+12"}, |
| - {1.33489e+012, "1.33489e+12"}, |
| - {1.33505e+012, "1.33505e+12"}, |
| - {1.33545e+009, "1335450000"}, |
| - {1.33503e+009, "1335030000"}, |
| + {1.33518e+012, "1335180000000.0"}, |
| + {1.33489e+012, "1334890000000.0"}, |
| + {1.33505e+012, "1335050000000.0"}, |
| + {1.33545e+009, "1335450000.0"}, |
| + {1.33503e+009, "1335030000.0"}, |
| }; |
| |
| for (size_t i = 0; i < arraysize(cases); ++i) { |
| @@ -836,12 +825,12 @@ TEST(StringNumberConversionsTest, DoubleToString) { |
| const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'}; |
| double input = 0; |
| memcpy(&input, input_bytes, arraysize(input_bytes)); |
| - EXPECT_EQ("1335179083776", NumberToString(input)); |
| + EXPECT_EQ("1335179083776.0", NumberToString(input)); |
| const char input_bytes2[8] = |
| {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'}; |
| input = 0; |
| memcpy(&input, input_bytes2, arraysize(input_bytes2)); |
| - EXPECT_EQ("1334890332160", NumberToString(input)); |
| + EXPECT_EQ("1334890332160.0", NumberToString(input)); |
| } |
| |
| TEST(StringNumberConversionsTest, HexEncode) { |