huangcm
2025-07-01 2af87f2bbd5ba07d377b5a7f0ee0e96053f2d424
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# 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) {