/src/double-conversion/double-conversion/string-to-double.cc
Line | Count | Source |
1 | | // Copyright 2010 the V8 project authors. All rights reserved. |
2 | | // Redistribution and use in source and binary forms, with or without |
3 | | // modification, are permitted provided that the following conditions are |
4 | | // met: |
5 | | // |
6 | | // * Redistributions of source code must retain the above copyright |
7 | | // notice, this list of conditions and the following disclaimer. |
8 | | // * Redistributions in binary form must reproduce the above |
9 | | // copyright notice, this list of conditions and the following |
10 | | // disclaimer in the documentation and/or other materials provided |
11 | | // with the distribution. |
12 | | // * Neither the name of Google Inc. nor the names of its |
13 | | // contributors may be used to endorse or promote products derived |
14 | | // from this software without specific prior written permission. |
15 | | // |
16 | | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 | | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 | | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 | | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 | | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 | | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 | | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 | | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | | |
28 | | #include <climits> |
29 | | #include <locale> |
30 | | #include <cmath> |
31 | | |
32 | | #include "string-to-double.h" |
33 | | |
34 | | #include "ieee.h" |
35 | | #include "strtod.h" |
36 | | #include "utils.h" |
37 | | |
38 | | #ifdef _MSC_VER |
39 | | # if _MSC_VER >= 1900 |
40 | | // Fix MSVC >= 2015 (_MSC_VER == 1900) warning |
41 | | // C4244: 'argument': conversion from 'const uc16' to 'char', possible loss of data |
42 | | // against Advance and friends, when instantiated with **it as char, not uc16. |
43 | | __pragma(warning(disable: 4244)) |
44 | | # endif |
45 | | # if _MSC_VER <= 1700 // VS2012, see IsDecimalDigitForRadix warning fix, below |
46 | | # define VS2012_RADIXWARN |
47 | | # endif |
48 | | #endif |
49 | | |
50 | | namespace double_conversion { |
51 | | |
52 | | namespace { |
53 | | |
54 | | // Widens an input character to its unsigned code-unit value. Symbol matching |
55 | | // compares characters in this form, so that a 16-bit input character is never |
56 | | // truncated into the range of the symbol byte it is compared against. |
57 | 12.0k | inline uint32_t CodeUnit(char ch) { |
58 | 12.0k | return static_cast<unsigned char>(ch); |
59 | 12.0k | } |
60 | | |
61 | 0 | inline uint32_t CodeUnit(uc16 ch) { |
62 | 0 | return ch; |
63 | 0 | } |
64 | | |
65 | 12.0k | inline uint32_t ToLower(uint32_t ch) { |
66 | 12.0k | if (ch > 0x7F) return ch; |
67 | 11.9k | static const std::ctype<char>& cType = |
68 | 11.9k | std::use_facet<std::ctype<char> >(std::locale::classic()); |
69 | 11.9k | return static_cast<unsigned char>(cType.tolower(static_cast<char>(ch))); |
70 | 12.0k | } |
71 | | |
72 | 0 | inline uint32_t Pass(uint32_t ch) { |
73 | 0 | return ch; |
74 | 0 | } |
75 | | |
76 | | template <class Iterator, class Converter> |
77 | | static inline bool ConsumeSubStringImpl(Iterator* current, |
78 | | Iterator end, |
79 | | const char* substring, |
80 | 20 | Converter converter) { |
81 | 20 | DOUBLE_CONVERSION_ASSERT( |
82 | 20 | converter(CodeUnit(**current)) == converter(CodeUnit(*substring))); |
83 | 31 | for (substring++; *substring != '\0'; substring++) { |
84 | 27 | ++*current; |
85 | 27 | if (*current == end || |
86 | 20 | converter(CodeUnit(**current)) != converter(CodeUnit(*substring))) { |
87 | 16 | return false; |
88 | 16 | } |
89 | 27 | } |
90 | 4 | ++*current; |
91 | 4 | return true; |
92 | 20 | } string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubStringImpl<char const*, unsigned int (*)(unsigned int)>(char const**, char const*, char const*, unsigned int (*)(unsigned int)) Line | Count | Source | 80 | 20 | Converter converter) { | 81 | 20 | DOUBLE_CONVERSION_ASSERT( | 82 | 20 | converter(CodeUnit(**current)) == converter(CodeUnit(*substring))); | 83 | 31 | for (substring++; *substring != '\0'; substring++) { | 84 | 27 | ++*current; | 85 | 27 | if (*current == end || | 86 | 20 | converter(CodeUnit(**current)) != converter(CodeUnit(*substring))) { | 87 | 16 | return false; | 88 | 16 | } | 89 | 27 | } | 90 | 4 | ++*current; | 91 | 4 | return true; | 92 | 20 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubStringImpl<unsigned short const*, unsigned int (*)(unsigned int)>(unsigned short const**, unsigned short const*, char const*, unsigned int (*)(unsigned int)) |
93 | | |
94 | | // Consumes the given substring from the iterator. |
95 | | // Returns false, if the substring does not match. |
96 | | template <class Iterator> |
97 | | static bool ConsumeSubString(Iterator* current, |
98 | | Iterator end, |
99 | | const char* substring, |
100 | 20 | bool allow_case_insensitivity) { |
101 | 20 | if (allow_case_insensitivity) { |
102 | 20 | return ConsumeSubStringImpl(current, end, substring, ToLower); |
103 | 20 | } else { |
104 | 0 | return ConsumeSubStringImpl(current, end, substring, Pass); |
105 | 0 | } |
106 | 20 | } string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubString<char const*>(char const**, char const*, char const*, bool) Line | Count | Source | 100 | 20 | bool allow_case_insensitivity) { | 101 | 20 | if (allow_case_insensitivity) { | 102 | 20 | return ConsumeSubStringImpl(current, end, substring, ToLower); | 103 | 20 | } else { | 104 | 0 | return ConsumeSubStringImpl(current, end, substring, Pass); | 105 | 0 | } | 106 | 20 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubString<unsigned short const*>(unsigned short const**, unsigned short const*, char const*, bool) |
107 | | |
108 | | // Consumes first character of the str is equal to ch |
109 | | template <class Char> |
110 | | inline bool ConsumeFirstCharacter(Char ch, |
111 | | const char* str, |
112 | 5.96k | bool case_insensitivity) { |
113 | 5.96k | const uint32_t c = CodeUnit(ch); |
114 | 5.96k | const uint32_t first = CodeUnit(str[0]); |
115 | 5.96k | return case_insensitivity ? ToLower(c) == ToLower(first) : c == first; |
116 | 5.96k | } string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeFirstCharacter<char>(char, char const*, bool) Line | Count | Source | 112 | 5.96k | bool case_insensitivity) { | 113 | 5.96k | const uint32_t c = CodeUnit(ch); | 114 | 5.96k | const uint32_t first = CodeUnit(str[0]); | 115 | 5.96k | return case_insensitivity ? ToLower(c) == ToLower(first) : c == first; | 116 | 5.96k | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeFirstCharacter<unsigned short>(unsigned short, char const*, bool) |
117 | | } // namespace |
118 | | |
119 | | // Maximum number of significant digits in decimal representation. |
120 | | // The longest possible double in decimal representation is |
121 | | // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 |
122 | | // (768 digits). If we parse a number whose first digits are equal to a |
123 | | // mean of 2 adjacent doubles (that could have up to 769 digits) the result |
124 | | // must be rounded to the bigger one unless the tail consists of zeros, so |
125 | | // we don't need to preserve all the digits. |
126 | | const int kMaxSignificantDigits = 772; |
127 | | |
128 | | |
129 | | static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 }; |
130 | | static const int kWhitespaceTable7Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7); |
131 | | |
132 | | |
133 | | static const uc16 kWhitespaceTable16[] = { |
134 | | 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, |
135 | | 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 |
136 | | }; |
137 | | static const int kWhitespaceTable16Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16); |
138 | | |
139 | | |
140 | 5.19k | static bool isWhitespace(int x) { |
141 | 5.19k | if (x < 128) { |
142 | 30.6k | for (int i = 0; i < kWhitespaceTable7Length; i++) { |
143 | 27.2k | if (kWhitespaceTable7[i] == x) return true; |
144 | 27.2k | } |
145 | 5.19k | } else { |
146 | 0 | for (int i = 0; i < kWhitespaceTable16Length; i++) { |
147 | 0 | if (kWhitespaceTable16[i] == x) return true; |
148 | 0 | } |
149 | 0 | } |
150 | 3.36k | return false; |
151 | 5.19k | } |
152 | | |
153 | | |
154 | | // Returns true if a nonspace found and false if the end has reached. |
155 | | template <class Iterator> |
156 | 4.86k | static inline bool AdvanceToNonspace(Iterator* current, Iterator end) { |
157 | 6.68k | while (*current != end) { |
158 | 5.19k | if (!isWhitespace(**current)) return true; |
159 | 1.82k | ++*current; |
160 | 1.82k | } |
161 | 1.49k | return false; |
162 | 4.86k | } string-to-double.cc:bool double_conversion::AdvanceToNonspace<char const*>(char const**, char const*) Line | Count | Source | 156 | 4.86k | static inline bool AdvanceToNonspace(Iterator* current, Iterator end) { | 157 | 6.68k | while (*current != end) { | 158 | 5.19k | if (!isWhitespace(**current)) return true; | 159 | 1.82k | ++*current; | 160 | 1.82k | } | 161 | 1.49k | return false; | 162 | 4.86k | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::AdvanceToNonspace<char*>(char**, char*) Unexecuted instantiation: string-to-double.cc:bool double_conversion::AdvanceToNonspace<unsigned short const*>(unsigned short const**, unsigned short const*) |
163 | | |
164 | | |
165 | 4.32M | static bool isDigit(int x, int radix) { |
166 | 4.32M | return (x >= '0' && x <= '9' && x < '0' + radix) |
167 | 57.2k | || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
168 | 5.10k | || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
169 | 4.32M | } |
170 | | |
171 | | |
172 | 38 | static double SignedZero(bool sign) { |
173 | 38 | return sign ? -0.0 : 0.0; |
174 | 38 | } |
175 | | |
176 | | |
177 | | // Returns true if 'c' is a decimal digit that is valid for the given radix. |
178 | | // |
179 | | // The function is small and could be inlined, but VS2012 emitted a warning |
180 | | // because it constant-propagated the radix and concluded that the last |
181 | | // condition was always true. Moving it into a separate function and |
182 | | // suppressing optimisation keeps the compiler from warning. |
183 | | #ifdef VS2012_RADIXWARN |
184 | | #pragma optimize("",off) |
185 | | static bool IsDecimalDigitForRadix(int c, int radix) { |
186 | | return '0' <= c && c <= '9' && (c - '0') < radix; |
187 | | } |
188 | | #pragma optimize("",on) |
189 | | #else |
190 | 1.11M | static bool inline IsDecimalDigitForRadix(int c, int radix) { |
191 | 1.11M | return '0' <= c && c <= '9' && (c - '0') < radix; |
192 | 1.11M | } |
193 | | #endif |
194 | | // Returns true if 'c' is a character digit that is valid for the given radix. |
195 | | // The 'a_character' should be 'a' or 'A'. |
196 | | // |
197 | | // The function is small and could be inlined, but VS2012 emitted a warning |
198 | | // because it constant-propagated the radix and concluded that the first |
199 | | // condition was always false. By moving it into a separate function the |
200 | | // compiler wouldn't warn anymore. |
201 | 3.64k | static bool IsCharacterDigitForRadix(int c, int radix, char a_character) { |
202 | 3.64k | return radix > 10 && c >= a_character && c < a_character + radix - 10; |
203 | 3.64k | } |
204 | | |
205 | | // Returns true, when the iterator is equal to end. |
206 | | template<class Iterator> |
207 | 9.57M | static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) { |
208 | 9.57M | if (separator == StringToDoubleConverter::kNoSeparator) { |
209 | 9.57M | ++(*it); |
210 | 9.57M | return *it == end; |
211 | 9.57M | } |
212 | 0 | if (!isDigit(**it, base)) { |
213 | 0 | ++(*it); |
214 | 0 | return *it == end; |
215 | 0 | } |
216 | 0 | ++(*it); |
217 | 0 | if (*it == end) return true; |
218 | 0 | if (*it + 1 == end) return false; |
219 | 0 | if (**it == separator && isDigit(*(*it + 1), base)) { |
220 | 0 | ++(*it); |
221 | 0 | } |
222 | 0 | return *it == end; |
223 | 0 | } string-to-double.cc:bool double_conversion::Advance<char const*>(char const**, unsigned short, int, char const*&) Line | Count | Source | 207 | 9.56M | static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) { | 208 | 9.56M | if (separator == StringToDoubleConverter::kNoSeparator) { | 209 | 9.56M | ++(*it); | 210 | 9.56M | return *it == end; | 211 | 9.56M | } | 212 | 0 | if (!isDigit(**it, base)) { | 213 | 0 | ++(*it); | 214 | 0 | return *it == end; | 215 | 0 | } | 216 | 0 | ++(*it); | 217 | 0 | if (*it == end) return true; | 218 | 0 | if (*it + 1 == end) return false; | 219 | 0 | if (**it == separator && isDigit(*(*it + 1), base)) { | 220 | 0 | ++(*it); | 221 | 0 | } | 222 | 0 | return *it == end; | 223 | 0 | } |
string-to-double.cc:bool double_conversion::Advance<char*>(char**, unsigned short, int, char*&) Line | Count | Source | 207 | 6.36k | static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) { | 208 | 6.36k | if (separator == StringToDoubleConverter::kNoSeparator) { | 209 | 6.36k | ++(*it); | 210 | 6.36k | return *it == end; | 211 | 6.36k | } | 212 | 0 | if (!isDigit(**it, base)) { | 213 | 0 | ++(*it); | 214 | 0 | return *it == end; | 215 | 0 | } | 216 | 0 | ++(*it); | 217 | 0 | if (*it == end) return true; | 218 | 0 | if (*it + 1 == end) return false; | 219 | 0 | if (**it == separator && isDigit(*(*it + 1), base)) { | 220 | 0 | ++(*it); | 221 | 0 | } | 222 | 0 | return *it == end; | 223 | 0 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::Advance<unsigned short const*>(unsigned short const**, unsigned short, int, unsigned short const*&) |
224 | | |
225 | | // Checks whether the string in the range start-end is a hex-float string. |
226 | | // This function assumes that the leading '0x'/'0X' is already consumed. |
227 | | // |
228 | | // Hex float strings are of one of the following forms: |
229 | | // - hex_digits+ 'p' ('+'|'-')? exponent_digits+ |
230 | | // - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+ |
231 | | // - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+ |
232 | | template<class Iterator> |
233 | | static bool IsHexFloatString(Iterator start, |
234 | | Iterator end, |
235 | | uc16 separator, |
236 | | bool allow_trailing_junk, |
237 | 798 | bool allow_trailing_spaces) { |
238 | 798 | DOUBLE_CONVERSION_ASSERT(start != end); |
239 | | |
240 | 798 | Iterator current = start; |
241 | | |
242 | 798 | bool saw_digit = false; |
243 | 1.05M | while (isDigit(*current, 16)) { |
244 | 1.05M | saw_digit = true; |
245 | 1.05M | if (Advance(¤t, separator, 16, end)) return false; |
246 | 1.05M | } |
247 | 582 | if (*current == '.') { |
248 | 122 | if (Advance(¤t, separator, 16, end)) return false; |
249 | 2.21M | while (isDigit(*current, 16)) { |
250 | 2.21M | saw_digit = true; |
251 | 2.21M | if (Advance(¤t, separator, 16, end)) return false; |
252 | 2.21M | } |
253 | 119 | } |
254 | 563 | if (!saw_digit) return false; |
255 | 506 | if (*current != 'p' && *current != 'P') return false; |
256 | | // The separator is only allowed between significand digits, not in the |
257 | | // exponent, so advance through the exponent with no separator. |
258 | 419 | const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator; |
259 | 419 | if (Advance(¤t, kNoSeparator, 16, end)) return false; |
260 | 415 | if (*current == '+' || *current == '-') { |
261 | 55 | if (Advance(¤t, kNoSeparator, 16, end)) return false; |
262 | 55 | } |
263 | 413 | if (!isDigit(*current, 10)) return false; |
264 | 394 | if (Advance(¤t, kNoSeparator, 16, end)) return true; |
265 | 1.95k | while (isDigit(*current, 10)) { |
266 | 1.92k | if (Advance(¤t, kNoSeparator, 16, end)) return true; |
267 | 1.92k | } |
268 | | // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it is |
269 | | // for decimal numbers. |
270 | 32 | if (allow_trailing_junk) return true; |
271 | 0 | return allow_trailing_spaces && !AdvanceToNonspace(¤t, end); |
272 | 32 | } string-to-double.cc:bool double_conversion::IsHexFloatString<char const*>(char const*, char const*, unsigned short, bool, bool) Line | Count | Source | 237 | 798 | bool allow_trailing_spaces) { | 238 | 798 | DOUBLE_CONVERSION_ASSERT(start != end); | 239 | | | 240 | 798 | Iterator current = start; | 241 | | | 242 | 798 | bool saw_digit = false; | 243 | 1.05M | while (isDigit(*current, 16)) { | 244 | 1.05M | saw_digit = true; | 245 | 1.05M | if (Advance(¤t, separator, 16, end)) return false; | 246 | 1.05M | } | 247 | 582 | if (*current == '.') { | 248 | 122 | if (Advance(¤t, separator, 16, end)) return false; | 249 | 2.21M | while (isDigit(*current, 16)) { | 250 | 2.21M | saw_digit = true; | 251 | 2.21M | if (Advance(¤t, separator, 16, end)) return false; | 252 | 2.21M | } | 253 | 119 | } | 254 | 563 | if (!saw_digit) return false; | 255 | 506 | if (*current != 'p' && *current != 'P') return false; | 256 | | // The separator is only allowed between significand digits, not in the | 257 | | // exponent, so advance through the exponent with no separator. | 258 | 419 | const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator; | 259 | 419 | if (Advance(¤t, kNoSeparator, 16, end)) return false; | 260 | 415 | if (*current == '+' || *current == '-') { | 261 | 55 | if (Advance(¤t, kNoSeparator, 16, end)) return false; | 262 | 55 | } | 263 | 413 | if (!isDigit(*current, 10)) return false; | 264 | 394 | if (Advance(¤t, kNoSeparator, 16, end)) return true; | 265 | 1.95k | while (isDigit(*current, 10)) { | 266 | 1.92k | if (Advance(¤t, kNoSeparator, 16, end)) return true; | 267 | 1.92k | } | 268 | | // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it is | 269 | | // for decimal numbers. | 270 | 32 | if (allow_trailing_junk) return true; | 271 | 0 | return allow_trailing_spaces && !AdvanceToNonspace(¤t, end); | 272 | 32 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::IsHexFloatString<char*>(char*, char*, unsigned short, bool, bool) Unexecuted instantiation: string-to-double.cc:bool double_conversion::IsHexFloatString<unsigned short const*>(unsigned short const*, unsigned short const*, unsigned short, bool, bool) |
273 | | |
274 | | |
275 | | // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
276 | | // |
277 | | // If parse_as_hex_float is true, then the string must be a valid |
278 | | // hex-float. |
279 | | template <int radix_log_2, class Iterator> |
280 | | static double RadixStringToIeee(Iterator* current, |
281 | | Iterator end, |
282 | | bool sign, |
283 | | uc16 separator, |
284 | | bool parse_as_hex_float, |
285 | | bool allow_trailing_junk, |
286 | | bool allow_trailing_spaces, |
287 | | double junk_string_value, |
288 | | bool read_as_double, |
289 | 744 | bool* result_is_junk) { |
290 | 744 | DOUBLE_CONVERSION_ASSERT(*current != end); |
291 | 744 | DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || |
292 | 744 | IsHexFloatString(*current, end, separator, allow_trailing_junk, |
293 | 744 | allow_trailing_spaces)); |
294 | | |
295 | 744 | const int kDoubleSize = Double::kSignificandSize; |
296 | 744 | const int kSingleSize = Single::kSignificandSize; |
297 | | // A hex-float is formed here as a double and rounded to float by the caller |
298 | | // (StringToFloat casts the result). Rounding the significand to single |
299 | | // precision here would double-round both subnormal floats and floats whose |
300 | | // exact significand exceeds 53 bits, so keep the full double significand and |
301 | | // round it to odd, which makes that final single-precision cast correct. |
302 | 744 | const bool round_hex_float_to_single = parse_as_hex_float && !read_as_double; |
303 | 744 | const int kSignificandSize = |
304 | 744 | (read_as_double || parse_as_hex_float) ? kDoubleSize : kSingleSize; |
305 | | |
306 | 744 | *result_is_junk = true; |
307 | | |
308 | 744 | int64_t number = 0; |
309 | 744 | int exponent = 0; |
310 | 744 | const int max_exponent = INT_MAX / 2; |
311 | 744 | const int radix = (1 << radix_log_2); |
312 | | // Whether we have encountered a '.' and are parsing the decimal digits. |
313 | | // Only relevant if parse_as_hex_float is true. |
314 | 744 | bool post_decimal = false; |
315 | | |
316 | | // Skip leading 0s. |
317 | 1.20k | while (**current == '0') { |
318 | 470 | if (Advance(current, separator, radix, end)) { |
319 | 8 | *result_is_junk = false; |
320 | 8 | return SignedZero(sign); |
321 | 8 | } |
322 | 470 | } |
323 | | |
324 | 1.11M | while (true) { |
325 | 1.11M | int digit; |
326 | 1.11M | if (IsDecimalDigitForRadix(**current, radix)) { |
327 | 1.11M | digit = static_cast<char>(**current) - '0'; |
328 | 1.11M | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; |
329 | 1.11M | } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { |
330 | 1.10k | digit = static_cast<char>(**current) - 'a' + 10; |
331 | 1.10k | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; |
332 | 1.27k | } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { |
333 | 983 | digit = static_cast<char>(**current) - 'A' + 10; |
334 | 983 | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; |
335 | 983 | } else if (parse_as_hex_float && **current == '.') { |
336 | 35 | post_decimal = true; |
337 | 35 | Advance(current, separator, radix, end); |
338 | 35 | DOUBLE_CONVERSION_ASSERT(*current != end); |
339 | 35 | continue; |
340 | 254 | } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { |
341 | 167 | break; |
342 | 167 | } else { |
343 | | // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it |
344 | | // is for decimal numbers. |
345 | 87 | if (allow_trailing_junk || |
346 | 87 | (allow_trailing_spaces && !AdvanceToNonspace(current, end))) { |
347 | 87 | break; |
348 | 87 | } else { |
349 | 0 | return junk_string_value; |
350 | 0 | } |
351 | 87 | } |
352 | | |
353 | 1.11M | number = number * radix + digit; |
354 | 1.11M | int overflow = static_cast<int>(number >> kSignificandSize); |
355 | 1.11M | if (overflow != 0) { |
356 | | // Overflow occurred. Need to determine which direction to round the |
357 | | // result. |
358 | 240 | int overflow_bits_count = 1; |
359 | 518 | while (overflow > 1) { |
360 | 278 | overflow_bits_count++; |
361 | 278 | overflow >>= 1; |
362 | 278 | } |
363 | | |
364 | 240 | int dropped_bits_mask = ((1 << overflow_bits_count) - 1); |
365 | 240 | int dropped_bits = static_cast<int>(number) & dropped_bits_mask; |
366 | 240 | number >>= overflow_bits_count; |
367 | 240 | exponent += overflow_bits_count; |
368 | | |
369 | 240 | bool zero_tail = true; |
370 | 1.05M | for (;;) { |
371 | 1.05M | if (Advance(current, separator, radix, end)) break; |
372 | 1.05M | if (parse_as_hex_float && **current == '.') { |
373 | | // Just run over the '.'. We are just trying to see whether there is |
374 | | // a non-zero digit somewhere. |
375 | 4 | Advance(current, separator, radix, end); |
376 | 4 | DOUBLE_CONVERSION_ASSERT(*current != end); |
377 | 4 | post_decimal = true; |
378 | 4 | } |
379 | 1.05M | if (!isDigit(**current, radix)) break; |
380 | 1.05M | zero_tail = zero_tail && **current == '0'; |
381 | 1.05M | if (!post_decimal) { |
382 | 1.05M | if (exponent <= max_exponent - radix_log_2) { |
383 | 1.05M | exponent += radix_log_2; |
384 | 1.05M | } else { |
385 | 0 | exponent = max_exponent; |
386 | 0 | } |
387 | 1.05M | } |
388 | 1.05M | } |
389 | | |
390 | 240 | if (!parse_as_hex_float && !allow_trailing_junk) { |
391 | 0 | if (allow_trailing_spaces ? AdvanceToNonspace(current, end) |
392 | 0 | : *current != end) { |
393 | 0 | return junk_string_value; |
394 | 0 | } |
395 | 0 | } |
396 | | |
397 | 240 | if (round_hex_float_to_single) { |
398 | | // Round the significand to odd: set the lowest kept bit whenever any |
399 | | // bit was dropped. The caller rounds this double to float; rounding to |
400 | | // nearest here would double-round, but round-to-odd leaves that final |
401 | | // single rounding correct for normal and subnormal results alike. |
402 | 0 | if (dropped_bits != 0 || !zero_tail) { |
403 | 0 | number |= 1; |
404 | 0 | } |
405 | 240 | } else { |
406 | 240 | int middle_value = (1 << (overflow_bits_count - 1)); |
407 | 240 | if (dropped_bits > middle_value) { |
408 | 48 | number++; // Rounding up. |
409 | 192 | } else if (dropped_bits == middle_value) { |
410 | | // Rounding to even to consistency with decimals: half-way case rounds |
411 | | // up if significant part is odd and down otherwise. |
412 | 56 | if ((number & 1) != 0 || !zero_tail) { |
413 | 39 | number++; // Rounding up. |
414 | 39 | } |
415 | 56 | } |
416 | | |
417 | | // Rounding up may cause overflow. |
418 | 240 | if ((number & ((int64_t)1 << kSignificandSize)) != 0) { |
419 | 6 | exponent++; |
420 | 6 | number >>= 1; |
421 | 6 | } |
422 | 240 | } |
423 | 240 | break; |
424 | 240 | } |
425 | 1.11M | if (Advance(current, separator, radix, end)) break; |
426 | 1.11M | } |
427 | | |
428 | 736 | DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); |
429 | 736 | DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); |
430 | | |
431 | 736 | *result_is_junk = false; |
432 | | |
433 | 736 | if (parse_as_hex_float) { |
434 | 197 | DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); |
435 | | // The separator is only allowed between significand digits, not in the |
436 | | // exponent, so advance through the exponent with no separator. This must |
437 | | // match IsHexFloatString, which validated the string the same way. |
438 | 197 | const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator; |
439 | 197 | Advance(current, kNoSeparator, radix, end); |
440 | 197 | DOUBLE_CONVERSION_ASSERT(*current != end); |
441 | 197 | bool is_negative = false; |
442 | 197 | if (**current == '+') { |
443 | 1 | Advance(current, kNoSeparator, radix, end); |
444 | 1 | DOUBLE_CONVERSION_ASSERT(*current != end); |
445 | 196 | } else if (**current == '-') { |
446 | 25 | is_negative = true; |
447 | 25 | Advance(current, kNoSeparator, radix, end); |
448 | 25 | DOUBLE_CONVERSION_ASSERT(*current != end); |
449 | 25 | } |
450 | 197 | int written_exponent = 0; |
451 | 1.17k | while (IsDecimalDigitForRadix(**current, 10)) { |
452 | | // No need to read exponents if they are too big. That could potentially overflow |
453 | | // the `written_exponent` variable. |
454 | 1.16k | if (abs(written_exponent) <= 100 * Double::kMaxExponent) { |
455 | 830 | written_exponent = 10 * written_exponent + **current - '0'; |
456 | 830 | } |
457 | 1.16k | if (Advance(current, kNoSeparator, radix, end)) break; |
458 | 1.16k | } |
459 | 197 | if (is_negative) written_exponent = -written_exponent; |
460 | 197 | const int64_t combined = static_cast<int64_t>(exponent) + written_exponent; |
461 | 197 | if (combined > max_exponent) { |
462 | 0 | exponent = max_exponent; |
463 | 197 | } else if (combined < -max_exponent) { |
464 | 0 | exponent = -max_exponent; |
465 | 197 | } else { |
466 | 197 | exponent = static_cast<int>(combined); |
467 | 197 | } |
468 | 197 | } |
469 | | |
470 | 736 | if (exponent == 0 || number == 0) { |
471 | 364 | if (sign) { |
472 | 107 | if (number == 0) return -0.0; |
473 | 106 | number = -number; |
474 | 106 | } |
475 | 363 | return static_cast<double>(number); |
476 | 364 | } |
477 | | |
478 | 372 | DOUBLE_CONVERSION_ASSERT(number != 0); |
479 | 372 | if (exponent > 100 * Double::kMaxExponent) { |
480 | 29 | return sign ? -Double::Infinity() : Double::Infinity(); |
481 | 29 | } |
482 | 343 | if (exponent < -100 * Double::kMaxExponent) { |
483 | 6 | return SignedZero(sign); |
484 | 6 | } |
485 | | // number is an exact integer below 2^kSignificandSize, so number * 2^exponent |
486 | | // can be formed directly. Double(DiyFp(number, exponent)) would instead assume |
487 | | // a normalized significand: a hex-float like "0x1p1000" or "0x2p-1075" reaches |
488 | | // here with a small number and a large exponent, which DiyFpToUint64 then reads |
489 | | // as an overflow (infinity) or underflow (zero) rather than the finite result. |
490 | 337 | double result = ldexp(static_cast<double>(number), exponent); |
491 | 337 | return sign ? -result : result; |
492 | 343 | } string-to-double.cc:double double_conversion::RadixStringToIeee<4, char const*>(char const**, char const*, bool, unsigned short, bool, bool, bool, double, bool, bool*) Line | Count | Source | 289 | 524 | bool* result_is_junk) { | 290 | 524 | DOUBLE_CONVERSION_ASSERT(*current != end); | 291 | 524 | DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || | 292 | 524 | IsHexFloatString(*current, end, separator, allow_trailing_junk, | 293 | 524 | allow_trailing_spaces)); | 294 | | | 295 | 524 | const int kDoubleSize = Double::kSignificandSize; | 296 | 524 | const int kSingleSize = Single::kSignificandSize; | 297 | | // A hex-float is formed here as a double and rounded to float by the caller | 298 | | // (StringToFloat casts the result). Rounding the significand to single | 299 | | // precision here would double-round both subnormal floats and floats whose | 300 | | // exact significand exceeds 53 bits, so keep the full double significand and | 301 | | // round it to odd, which makes that final single-precision cast correct. | 302 | 524 | const bool round_hex_float_to_single = parse_as_hex_float && !read_as_double; | 303 | 524 | const int kSignificandSize = | 304 | 524 | (read_as_double || parse_as_hex_float) ? kDoubleSize : kSingleSize; | 305 | | | 306 | 524 | *result_is_junk = true; | 307 | | | 308 | 524 | int64_t number = 0; | 309 | 524 | int exponent = 0; | 310 | 524 | const int max_exponent = INT_MAX / 2; | 311 | 524 | const int radix = (1 << radix_log_2); | 312 | | // Whether we have encountered a '.' and are parsing the decimal digits. | 313 | | // Only relevant if parse_as_hex_float is true. | 314 | 524 | bool post_decimal = false; | 315 | | | 316 | | // Skip leading 0s. | 317 | 986 | while (**current == '0') { | 318 | 470 | if (Advance(current, separator, radix, end)) { | 319 | 8 | *result_is_junk = false; | 320 | 8 | return SignedZero(sign); | 321 | 8 | } | 322 | 470 | } | 323 | | | 324 | 1.10M | while (true) { | 325 | 1.10M | int digit; | 326 | 1.10M | if (IsDecimalDigitForRadix(**current, radix)) { | 327 | 1.10M | digit = static_cast<char>(**current) - '0'; | 328 | 1.10M | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; | 329 | 1.10M | } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { | 330 | 1.10k | digit = static_cast<char>(**current) - 'a' + 10; | 331 | 1.10k | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; | 332 | 1.27k | } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { | 333 | 983 | digit = static_cast<char>(**current) - 'A' + 10; | 334 | 983 | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; | 335 | 983 | } else if (parse_as_hex_float && **current == '.') { | 336 | 35 | post_decimal = true; | 337 | 35 | Advance(current, separator, radix, end); | 338 | 35 | DOUBLE_CONVERSION_ASSERT(*current != end); | 339 | 35 | continue; | 340 | 254 | } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { | 341 | 167 | break; | 342 | 167 | } else { | 343 | | // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it | 344 | | // is for decimal numbers. | 345 | 87 | if (allow_trailing_junk || | 346 | 87 | (allow_trailing_spaces && !AdvanceToNonspace(current, end))) { | 347 | 87 | break; | 348 | 87 | } else { | 349 | 0 | return junk_string_value; | 350 | 0 | } | 351 | 87 | } | 352 | | | 353 | 1.10M | number = number * radix + digit; | 354 | 1.10M | int overflow = static_cast<int>(number >> kSignificandSize); | 355 | 1.10M | if (overflow != 0) { | 356 | | // Overflow occurred. Need to determine which direction to round the | 357 | | // result. | 358 | 135 | int overflow_bits_count = 1; | 359 | 386 | while (overflow > 1) { | 360 | 251 | overflow_bits_count++; | 361 | 251 | overflow >>= 1; | 362 | 251 | } | 363 | | | 364 | 135 | int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 365 | 135 | int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 366 | 135 | number >>= overflow_bits_count; | 367 | 135 | exponent += overflow_bits_count; | 368 | | | 369 | 135 | bool zero_tail = true; | 370 | 1.05M | for (;;) { | 371 | 1.05M | if (Advance(current, separator, radix, end)) break; | 372 | 1.05M | if (parse_as_hex_float && **current == '.') { | 373 | | // Just run over the '.'. We are just trying to see whether there is | 374 | | // a non-zero digit somewhere. | 375 | 4 | Advance(current, separator, radix, end); | 376 | 4 | DOUBLE_CONVERSION_ASSERT(*current != end); | 377 | 4 | post_decimal = true; | 378 | 4 | } | 379 | 1.05M | if (!isDigit(**current, radix)) break; | 380 | 1.05M | zero_tail = zero_tail && **current == '0'; | 381 | 1.05M | if (!post_decimal) { | 382 | 1.04M | if (exponent <= max_exponent - radix_log_2) { | 383 | 1.04M | exponent += radix_log_2; | 384 | 1.04M | } else { | 385 | 0 | exponent = max_exponent; | 386 | 0 | } | 387 | 1.04M | } | 388 | 1.05M | } | 389 | | | 390 | 135 | if (!parse_as_hex_float && !allow_trailing_junk) { | 391 | 0 | if (allow_trailing_spaces ? AdvanceToNonspace(current, end) | 392 | 0 | : *current != end) { | 393 | 0 | return junk_string_value; | 394 | 0 | } | 395 | 0 | } | 396 | | | 397 | 135 | if (round_hex_float_to_single) { | 398 | | // Round the significand to odd: set the lowest kept bit whenever any | 399 | | // bit was dropped. The caller rounds this double to float; rounding to | 400 | | // nearest here would double-round, but round-to-odd leaves that final | 401 | | // single rounding correct for normal and subnormal results alike. | 402 | 0 | if (dropped_bits != 0 || !zero_tail) { | 403 | 0 | number |= 1; | 404 | 0 | } | 405 | 135 | } else { | 406 | 135 | int middle_value = (1 << (overflow_bits_count - 1)); | 407 | 135 | if (dropped_bits > middle_value) { | 408 | 45 | number++; // Rounding up. | 409 | 90 | } else if (dropped_bits == middle_value) { | 410 | | // Rounding to even to consistency with decimals: half-way case rounds | 411 | | // up if significant part is odd and down otherwise. | 412 | 18 | if ((number & 1) != 0 || !zero_tail) { | 413 | 14 | number++; // Rounding up. | 414 | 14 | } | 415 | 18 | } | 416 | | | 417 | | // Rounding up may cause overflow. | 418 | 135 | if ((number & ((int64_t)1 << kSignificandSize)) != 0) { | 419 | 5 | exponent++; | 420 | 5 | number >>= 1; | 421 | 5 | } | 422 | 135 | } | 423 | 135 | break; | 424 | 135 | } | 425 | 1.10M | if (Advance(current, separator, radix, end)) break; | 426 | 1.10M | } | 427 | | | 428 | 516 | DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); | 429 | 516 | DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); | 430 | | | 431 | 516 | *result_is_junk = false; | 432 | | | 433 | 516 | if (parse_as_hex_float) { | 434 | 197 | DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); | 435 | | // The separator is only allowed between significand digits, not in the | 436 | | // exponent, so advance through the exponent with no separator. This must | 437 | | // match IsHexFloatString, which validated the string the same way. | 438 | 197 | const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator; | 439 | 197 | Advance(current, kNoSeparator, radix, end); | 440 | 197 | DOUBLE_CONVERSION_ASSERT(*current != end); | 441 | 197 | bool is_negative = false; | 442 | 197 | if (**current == '+') { | 443 | 1 | Advance(current, kNoSeparator, radix, end); | 444 | 1 | DOUBLE_CONVERSION_ASSERT(*current != end); | 445 | 196 | } else if (**current == '-') { | 446 | 25 | is_negative = true; | 447 | 25 | Advance(current, kNoSeparator, radix, end); | 448 | 25 | DOUBLE_CONVERSION_ASSERT(*current != end); | 449 | 25 | } | 450 | 197 | int written_exponent = 0; | 451 | 1.17k | while (IsDecimalDigitForRadix(**current, 10)) { | 452 | | // No need to read exponents if they are too big. That could potentially overflow | 453 | | // the `written_exponent` variable. | 454 | 1.16k | if (abs(written_exponent) <= 100 * Double::kMaxExponent) { | 455 | 830 | written_exponent = 10 * written_exponent + **current - '0'; | 456 | 830 | } | 457 | 1.16k | if (Advance(current, kNoSeparator, radix, end)) break; | 458 | 1.16k | } | 459 | 197 | if (is_negative) written_exponent = -written_exponent; | 460 | 197 | const int64_t combined = static_cast<int64_t>(exponent) + written_exponent; | 461 | 197 | if (combined > max_exponent) { | 462 | 0 | exponent = max_exponent; | 463 | 197 | } else if (combined < -max_exponent) { | 464 | 0 | exponent = -max_exponent; | 465 | 197 | } else { | 466 | 197 | exponent = static_cast<int>(combined); | 467 | 197 | } | 468 | 197 | } | 469 | | | 470 | 516 | if (exponent == 0 || number == 0) { | 471 | 249 | if (sign) { | 472 | 54 | if (number == 0) return -0.0; | 473 | 53 | number = -number; | 474 | 53 | } | 475 | 248 | return static_cast<double>(number); | 476 | 249 | } | 477 | | | 478 | 267 | DOUBLE_CONVERSION_ASSERT(number != 0); | 479 | 267 | if (exponent > 100 * Double::kMaxExponent) { | 480 | 29 | return sign ? -Double::Infinity() : Double::Infinity(); | 481 | 29 | } | 482 | 238 | if (exponent < -100 * Double::kMaxExponent) { | 483 | 6 | return SignedZero(sign); | 484 | 6 | } | 485 | | // number is an exact integer below 2^kSignificandSize, so number * 2^exponent | 486 | | // can be formed directly. Double(DiyFp(number, exponent)) would instead assume | 487 | | // a normalized significand: a hex-float like "0x1p1000" or "0x2p-1075" reaches | 488 | | // here with a small number and a large exponent, which DiyFpToUint64 then reads | 489 | | // as an overflow (infinity) or underflow (zero) rather than the finite result. | 490 | 232 | double result = ldexp(static_cast<double>(number), exponent); | 491 | 232 | return sign ? -result : result; | 492 | 238 | } |
string-to-double.cc:double double_conversion::RadixStringToIeee<3, char*>(char**, char*, bool, unsigned short, bool, bool, bool, double, bool, bool*) Line | Count | Source | 289 | 220 | bool* result_is_junk) { | 290 | 220 | DOUBLE_CONVERSION_ASSERT(*current != end); | 291 | 220 | DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || | 292 | 220 | IsHexFloatString(*current, end, separator, allow_trailing_junk, | 293 | 220 | allow_trailing_spaces)); | 294 | | | 295 | 220 | const int kDoubleSize = Double::kSignificandSize; | 296 | 220 | const int kSingleSize = Single::kSignificandSize; | 297 | | // A hex-float is formed here as a double and rounded to float by the caller | 298 | | // (StringToFloat casts the result). Rounding the significand to single | 299 | | // precision here would double-round both subnormal floats and floats whose | 300 | | // exact significand exceeds 53 bits, so keep the full double significand and | 301 | | // round it to odd, which makes that final single-precision cast correct. | 302 | 220 | const bool round_hex_float_to_single = parse_as_hex_float && !read_as_double; | 303 | 220 | const int kSignificandSize = | 304 | 220 | (read_as_double || parse_as_hex_float) ? kDoubleSize : kSingleSize; | 305 | | | 306 | 220 | *result_is_junk = true; | 307 | | | 308 | 220 | int64_t number = 0; | 309 | 220 | int exponent = 0; | 310 | 220 | const int max_exponent = INT_MAX / 2; | 311 | 220 | const int radix = (1 << radix_log_2); | 312 | | // Whether we have encountered a '.' and are parsing the decimal digits. | 313 | | // Only relevant if parse_as_hex_float is true. | 314 | 220 | bool post_decimal = false; | 315 | | | 316 | | // Skip leading 0s. | 317 | 220 | while (**current == '0') { | 318 | 0 | if (Advance(current, separator, radix, end)) { | 319 | 0 | *result_is_junk = false; | 320 | 0 | return SignedZero(sign); | 321 | 0 | } | 322 | 0 | } | 323 | | | 324 | 2.90k | while (true) { | 325 | 2.90k | int digit; | 326 | 2.90k | if (IsDecimalDigitForRadix(**current, radix)) { | 327 | 2.90k | digit = static_cast<char>(**current) - '0'; | 328 | 2.90k | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; | 329 | 2.90k | } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { | 330 | 0 | digit = static_cast<char>(**current) - 'a' + 10; | 331 | 0 | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; | 332 | 0 | } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { | 333 | 0 | digit = static_cast<char>(**current) - 'A' + 10; | 334 | 0 | if (post_decimal && exponent > -(max_exponent / 2)) exponent -= radix_log_2; | 335 | 0 | } else if (parse_as_hex_float && **current == '.') { | 336 | 0 | post_decimal = true; | 337 | 0 | Advance(current, separator, radix, end); | 338 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 339 | 0 | continue; | 340 | 0 | } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { | 341 | 0 | break; | 342 | 0 | } else { | 343 | | // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it | 344 | | // is for decimal numbers. | 345 | 0 | if (allow_trailing_junk || | 346 | 0 | (allow_trailing_spaces && !AdvanceToNonspace(current, end))) { | 347 | 0 | break; | 348 | 0 | } else { | 349 | 0 | return junk_string_value; | 350 | 0 | } | 351 | 0 | } | 352 | | | 353 | 2.90k | number = number * radix + digit; | 354 | 2.90k | int overflow = static_cast<int>(number >> kSignificandSize); | 355 | 2.90k | if (overflow != 0) { | 356 | | // Overflow occurred. Need to determine which direction to round the | 357 | | // result. | 358 | 105 | int overflow_bits_count = 1; | 359 | 132 | while (overflow > 1) { | 360 | 27 | overflow_bits_count++; | 361 | 27 | overflow >>= 1; | 362 | 27 | } | 363 | | | 364 | 105 | int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 365 | 105 | int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 366 | 105 | number >>= overflow_bits_count; | 367 | 105 | exponent += overflow_bits_count; | 368 | | | 369 | 105 | bool zero_tail = true; | 370 | 3.57k | for (;;) { | 371 | 3.57k | if (Advance(current, separator, radix, end)) break; | 372 | 3.46k | if (parse_as_hex_float && **current == '.') { | 373 | | // Just run over the '.'. We are just trying to see whether there is | 374 | | // a non-zero digit somewhere. | 375 | 0 | Advance(current, separator, radix, end); | 376 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 377 | 0 | post_decimal = true; | 378 | 0 | } | 379 | 3.46k | if (!isDigit(**current, radix)) break; | 380 | 3.46k | zero_tail = zero_tail && **current == '0'; | 381 | 3.46k | if (!post_decimal) { | 382 | 3.46k | if (exponent <= max_exponent - radix_log_2) { | 383 | 3.46k | exponent += radix_log_2; | 384 | 3.46k | } else { | 385 | 0 | exponent = max_exponent; | 386 | 0 | } | 387 | 3.46k | } | 388 | 3.46k | } | 389 | | | 390 | 105 | if (!parse_as_hex_float && !allow_trailing_junk) { | 391 | 0 | if (allow_trailing_spaces ? AdvanceToNonspace(current, end) | 392 | 0 | : *current != end) { | 393 | 0 | return junk_string_value; | 394 | 0 | } | 395 | 0 | } | 396 | | | 397 | 105 | if (round_hex_float_to_single) { | 398 | | // Round the significand to odd: set the lowest kept bit whenever any | 399 | | // bit was dropped. The caller rounds this double to float; rounding to | 400 | | // nearest here would double-round, but round-to-odd leaves that final | 401 | | // single rounding correct for normal and subnormal results alike. | 402 | 0 | if (dropped_bits != 0 || !zero_tail) { | 403 | 0 | number |= 1; | 404 | 0 | } | 405 | 105 | } else { | 406 | 105 | int middle_value = (1 << (overflow_bits_count - 1)); | 407 | 105 | if (dropped_bits > middle_value) { | 408 | 3 | number++; // Rounding up. | 409 | 102 | } else if (dropped_bits == middle_value) { | 410 | | // Rounding to even to consistency with decimals: half-way case rounds | 411 | | // up if significant part is odd and down otherwise. | 412 | 38 | if ((number & 1) != 0 || !zero_tail) { | 413 | 25 | number++; // Rounding up. | 414 | 25 | } | 415 | 38 | } | 416 | | | 417 | | // Rounding up may cause overflow. | 418 | 105 | if ((number & ((int64_t)1 << kSignificandSize)) != 0) { | 419 | 1 | exponent++; | 420 | 1 | number >>= 1; | 421 | 1 | } | 422 | 105 | } | 423 | 105 | break; | 424 | 105 | } | 425 | 2.79k | if (Advance(current, separator, radix, end)) break; | 426 | 2.79k | } | 427 | | | 428 | 220 | DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); | 429 | 220 | DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); | 430 | | | 431 | 220 | *result_is_junk = false; | 432 | | | 433 | 220 | if (parse_as_hex_float) { | 434 | 0 | DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); | 435 | | // The separator is only allowed between significand digits, not in the | 436 | | // exponent, so advance through the exponent with no separator. This must | 437 | | // match IsHexFloatString, which validated the string the same way. | 438 | 0 | const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator; | 439 | 0 | Advance(current, kNoSeparator, radix, end); | 440 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 441 | 0 | bool is_negative = false; | 442 | 0 | if (**current == '+') { | 443 | 0 | Advance(current, kNoSeparator, radix, end); | 444 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 445 | 0 | } else if (**current == '-') { | 446 | 0 | is_negative = true; | 447 | 0 | Advance(current, kNoSeparator, radix, end); | 448 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 449 | 0 | } | 450 | 0 | int written_exponent = 0; | 451 | 0 | while (IsDecimalDigitForRadix(**current, 10)) { | 452 | | // No need to read exponents if they are too big. That could potentially overflow | 453 | | // the `written_exponent` variable. | 454 | 0 | if (abs(written_exponent) <= 100 * Double::kMaxExponent) { | 455 | 0 | written_exponent = 10 * written_exponent + **current - '0'; | 456 | 0 | } | 457 | 0 | if (Advance(current, kNoSeparator, radix, end)) break; | 458 | 0 | } | 459 | 0 | if (is_negative) written_exponent = -written_exponent; | 460 | 0 | const int64_t combined = static_cast<int64_t>(exponent) + written_exponent; | 461 | 0 | if (combined > max_exponent) { | 462 | 0 | exponent = max_exponent; | 463 | 0 | } else if (combined < -max_exponent) { | 464 | 0 | exponent = -max_exponent; | 465 | 0 | } else { | 466 | 0 | exponent = static_cast<int>(combined); | 467 | 0 | } | 468 | 0 | } | 469 | | | 470 | 220 | if (exponent == 0 || number == 0) { | 471 | 115 | if (sign) { | 472 | 53 | if (number == 0) return -0.0; | 473 | 53 | number = -number; | 474 | 53 | } | 475 | 115 | return static_cast<double>(number); | 476 | 115 | } | 477 | | | 478 | 105 | DOUBLE_CONVERSION_ASSERT(number != 0); | 479 | 105 | if (exponent > 100 * Double::kMaxExponent) { | 480 | 0 | return sign ? -Double::Infinity() : Double::Infinity(); | 481 | 0 | } | 482 | 105 | if (exponent < -100 * Double::kMaxExponent) { | 483 | 0 | return SignedZero(sign); | 484 | 0 | } | 485 | | // number is an exact integer below 2^kSignificandSize, so number * 2^exponent | 486 | | // can be formed directly. Double(DiyFp(number, exponent)) would instead assume | 487 | | // a normalized significand: a hex-float like "0x1p1000" or "0x2p-1075" reaches | 488 | | // here with a small number and a large exponent, which DiyFpToUint64 then reads | 489 | | // as an overflow (infinity) or underflow (zero) rather than the finite result. | 490 | 105 | double result = ldexp(static_cast<double>(number), exponent); | 491 | 105 | return sign ? -result : result; | 492 | 105 | } |
Unexecuted instantiation: string-to-double.cc:double double_conversion::RadixStringToIeee<4, unsigned short const*>(unsigned short const**, unsigned short const*, bool, unsigned short, bool, bool, bool, double, bool, bool*) |
493 | | |
494 | | template <class Iterator> |
495 | | double StringToDoubleConverter::StringToIeee( |
496 | | Iterator input, |
497 | | int length, |
498 | | bool read_as_double, |
499 | 3.01k | int* processed_characters_count) const { |
500 | 3.01k | Iterator current = input; |
501 | 3.01k | Iterator end = input + length; |
502 | | |
503 | 3.01k | *processed_characters_count = 0; |
504 | | |
505 | 3.01k | const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; |
506 | 3.01k | const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; |
507 | 3.01k | const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; |
508 | 3.01k | const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; |
509 | 3.01k | const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0; |
510 | | |
511 | | // To make sure that iterator dereferencing is valid the following |
512 | | // convention is used: |
513 | | // 1. Each '++current' statement is followed by check for equality to 'end'. |
514 | | // 2. If AdvanceToNonspace returned false then current == end. |
515 | | // 3. If 'current' becomes equal to 'end' the function returns or goes to |
516 | | // 'parsing_done'. |
517 | | // 4. 'current' is not dereferenced after the 'parsing_done' label. |
518 | | // 5. Code before 'parsing_done' may rely on 'current != end'. |
519 | 3.01k | if (current == end) return empty_string_value_; |
520 | | |
521 | 3.01k | if (allow_leading_spaces || allow_trailing_spaces) { |
522 | 3.01k | if (!AdvanceToNonspace(¤t, end)) { |
523 | 12 | *processed_characters_count = static_cast<int>(current - input); |
524 | 12 | return empty_string_value_; |
525 | 12 | } |
526 | 3.00k | if (!allow_leading_spaces && (input != current)) { |
527 | | // No leading spaces allowed, but AdvanceToNonspace moved forward. |
528 | 0 | return junk_string_value_; |
529 | 0 | } |
530 | 3.00k | } |
531 | | |
532 | | // Exponent will be adjusted if insignificant digits of the integer part |
533 | | // or insignificant leading zeros of the fractional part are dropped. |
534 | 3.00k | int exponent = 0; |
535 | | // Leading fractional zeros and dropped integer digits are both moved into the |
536 | | // exponent, and both are bounded only by the input length. Saturating the |
537 | | // accumulation at this magnitude keeps it inside int; any exponent this large |
538 | | // is far outside the double range, so the clamped result is unchanged. |
539 | 3.00k | const int max_exponent = INT_MAX / 2; |
540 | 3.00k | int significant_digits = 0; |
541 | 3.00k | int insignificant_digits = 0; |
542 | 3.00k | bool nonzero_digit_dropped = false; |
543 | | |
544 | 3.00k | bool sign = false; |
545 | | |
546 | 3.00k | if (*current == '+' || *current == '-') { |
547 | 144 | sign = (*current == '-'); |
548 | 144 | ++current; |
549 | 144 | Iterator next_non_space = current; |
550 | | // Skip following spaces (if allowed). |
551 | 144 | if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; |
552 | 129 | if (!allow_spaces_after_sign && (current != next_non_space)) { |
553 | 0 | return junk_string_value_; |
554 | 0 | } |
555 | 129 | current = next_non_space; |
556 | 129 | } |
557 | | |
558 | 2.98k | if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) { |
559 | 2.98k | if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) { |
560 | 9 | if (!ConsumeSubString(¤t, end, infinity_symbol_, allow_case_insensitivity)) { |
561 | 7 | return junk_string_value_; |
562 | 7 | } |
563 | | |
564 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
565 | 0 | return junk_string_value_; |
566 | 0 | } |
567 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
568 | 0 | return junk_string_value_; |
569 | 0 | } |
570 | | |
571 | 2 | *processed_characters_count = static_cast<int>(current - input); |
572 | 2 | return sign ? -Double::Infinity() : Double::Infinity(); |
573 | 2 | } |
574 | 2.98k | } |
575 | | |
576 | 2.97k | if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) { |
577 | 2.97k | if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) { |
578 | 11 | if (!ConsumeSubString(¤t, end, nan_symbol_, allow_case_insensitivity)) { |
579 | 9 | return junk_string_value_; |
580 | 9 | } |
581 | | |
582 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
583 | 0 | return junk_string_value_; |
584 | 0 | } |
585 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
586 | 0 | return junk_string_value_; |
587 | 0 | } |
588 | | |
589 | 2 | *processed_characters_count = static_cast<int>(current - input); |
590 | 2 | return sign ? -Double::NaN() : Double::NaN(); |
591 | 2 | } |
592 | 2.97k | } |
593 | | |
594 | 2.96k | bool leading_zero = false; |
595 | 2.96k | if (*current == '0') { |
596 | 904 | if (Advance(¤t, separator_, 10, end)) { |
597 | 2 | *processed_characters_count = static_cast<int>(current - input); |
598 | 2 | return SignedZero(sign); |
599 | 2 | } |
600 | | |
601 | 902 | leading_zero = true; |
602 | | |
603 | | // It could be hexadecimal value. |
604 | 902 | if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) && |
605 | 902 | (*current == 'x' || *current == 'X')) { |
606 | 603 | ++current; |
607 | | |
608 | 603 | if (current == end) return junk_string_value_; // "0x" |
609 | | |
610 | 601 | bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && |
611 | 601 | IsHexFloatString(current, end, separator_, allow_trailing_junk, |
612 | 601 | allow_trailing_spaces); |
613 | | |
614 | 601 | if (!parse_as_hex_float && !isDigit(*current, 16)) { |
615 | 77 | return junk_string_value_; |
616 | 77 | } |
617 | | |
618 | 524 | bool result_is_junk; |
619 | 524 | double result = RadixStringToIeee<4>(¤t, |
620 | 524 | end, |
621 | 524 | sign, |
622 | 524 | separator_, |
623 | 524 | parse_as_hex_float, |
624 | 524 | allow_trailing_junk, |
625 | 524 | allow_trailing_spaces, |
626 | 524 | junk_string_value_, |
627 | 524 | read_as_double, |
628 | 524 | &result_is_junk); |
629 | 524 | if (!result_is_junk) { |
630 | 524 | if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); |
631 | 524 | *processed_characters_count = static_cast<int>(current - input); |
632 | 524 | } |
633 | 524 | return result; |
634 | 601 | } |
635 | | |
636 | | // Ignore leading zeros in the integer part. |
637 | 682 | while (*current == '0') { |
638 | 391 | if (Advance(¤t, separator_, 10, end)) { |
639 | 8 | *processed_characters_count = static_cast<int>(current - input); |
640 | 8 | return SignedZero(sign); |
641 | 8 | } |
642 | 391 | } |
643 | 299 | } |
644 | | |
645 | 2.35k | bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0; |
646 | | |
647 | | // The longest form of simplified number is: "-<significant digits>.1eXXX\0". |
648 | 2.35k | const int kBufferSize = kMaxSignificantDigits + 10; |
649 | 2.35k | DOUBLE_CONVERSION_STACK_UNINITIALIZED char |
650 | 2.35k | buffer[kBufferSize]; // NOLINT: size is known at compile time. |
651 | 2.35k | int buffer_pos = 0; |
652 | | |
653 | | // Copy significant digits of the integer part (if any) to the buffer. |
654 | 74.7k | while (*current >= '0' && *current <= '9') { |
655 | 73.2k | if (significant_digits < kMaxSignificantDigits) { |
656 | 72.1k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); |
657 | 72.1k | buffer[buffer_pos++] = static_cast<char>(*current); |
658 | 72.1k | significant_digits++; |
659 | | // Will later check if it's an octal in the buffer. |
660 | 72.1k | } else { |
661 | 1.07k | insignificant_digits++; // Move the digit into the exponential part. |
662 | 1.07k | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
663 | 1.07k | } |
664 | 73.2k | octal = octal && *current < '8'; |
665 | 73.2k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; |
666 | 73.2k | } |
667 | | |
668 | 1.59k | if (significant_digits == 0) { |
669 | 311 | octal = false; |
670 | 311 | } |
671 | | |
672 | 1.59k | if (*current == '.') { |
673 | 416 | if (octal && !allow_trailing_junk) return junk_string_value_; |
674 | 416 | if (octal) goto parsing_done; |
675 | | |
676 | 415 | if (Advance(¤t, separator_, 10, end)) { |
677 | 4 | if (significant_digits == 0 && !leading_zero) { |
678 | 2 | return junk_string_value_; |
679 | 2 | } else { |
680 | 2 | goto parsing_done; |
681 | 2 | } |
682 | 4 | } |
683 | | |
684 | 411 | if (significant_digits == 0) { |
685 | | // octal = false; |
686 | | // Integer part consists of 0 or is absent. Significant digits start after |
687 | | // leading zeros (if any). |
688 | 3.99M | while (*current == '0') { |
689 | 3.99M | if (Advance(¤t, separator_, 10, end)) { |
690 | 14 | *processed_characters_count = static_cast<int>(current - input); |
691 | 14 | return SignedZero(sign); |
692 | 14 | } |
693 | | // Saturate to avoid underflow on a pathologically long zero run. |
694 | 3.99M | if (exponent > -(max_exponent / 2)) exponent--; // Move this 0 into the exponent. |
695 | 3.99M | } |
696 | 173 | } |
697 | | |
698 | | // There is a fractional part. |
699 | | // We don't emit a '.', but adjust the exponent instead. |
700 | 69.3k | while (*current >= '0' && *current <= '9') { |
701 | 69.2k | if (significant_digits < kMaxSignificantDigits) { |
702 | 65.4k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); |
703 | 65.4k | buffer[buffer_pos++] = static_cast<char>(*current); |
704 | 65.4k | significant_digits++; |
705 | 65.4k | if (exponent > -(max_exponent / 2)) exponent--; |
706 | 65.4k | } else { |
707 | | // Ignore insignificant digits in the fractional part. |
708 | 3.83k | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
709 | 3.83k | } |
710 | 69.2k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; |
711 | 69.2k | } |
712 | 397 | } |
713 | | |
714 | 1.29k | if (!leading_zero && exponent == 0 && significant_digits == 0) { |
715 | | // If leading_zeros is true then the string contains zeros. |
716 | | // If exponent < 0 then string was [+-]\.0*... |
717 | | // If significant_digits != 0 the string is not equal to 0. |
718 | | // Otherwise there are no digits in the string. |
719 | 89 | return junk_string_value_; |
720 | 89 | } |
721 | | |
722 | | // Parse exponential part. |
723 | 1.20k | if (*current == 'e' || *current == 'E') { |
724 | 1.09k | if (octal && !allow_trailing_junk) return junk_string_value_; |
725 | 1.09k | if (octal) goto parsing_done; |
726 | 1.09k | Iterator junk_begin = current; |
727 | 1.09k | ++current; |
728 | 1.09k | if (current == end) { |
729 | 2 | if (allow_trailing_junk) { |
730 | 2 | current = junk_begin; |
731 | 2 | goto parsing_done; |
732 | 2 | } else { |
733 | 0 | return junk_string_value_; |
734 | 0 | } |
735 | 2 | } |
736 | 1.08k | char exponen_sign = '+'; |
737 | 1.08k | if (*current == '+' || *current == '-') { |
738 | 390 | exponen_sign = static_cast<char>(*current); |
739 | 390 | ++current; |
740 | 390 | if (current == end) { |
741 | 2 | if (allow_trailing_junk) { |
742 | 2 | current = junk_begin; |
743 | 2 | goto parsing_done; |
744 | 2 | } else { |
745 | 0 | return junk_string_value_; |
746 | 0 | } |
747 | 2 | } |
748 | 390 | } |
749 | | |
750 | 1.08k | if (current == end || *current < '0' || *current > '9') { |
751 | 22 | if (allow_trailing_junk) { |
752 | 22 | current = junk_begin; |
753 | 22 | goto parsing_done; |
754 | 22 | } else { |
755 | 0 | return junk_string_value_; |
756 | 0 | } |
757 | 22 | } |
758 | | |
759 | 1.06k | DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); |
760 | 1.06k | int num = 0; |
761 | 4.18k | do { |
762 | | // Check overflow. |
763 | 4.18k | int digit = *current - '0'; |
764 | 4.18k | if (num >= max_exponent / 10 |
765 | 396 | && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { |
766 | 393 | num = max_exponent; |
767 | 3.78k | } else { |
768 | 3.78k | num = num * 10 + digit; |
769 | 3.78k | } |
770 | 4.18k | ++current; |
771 | 4.18k | } while (current != end && *current >= '0' && *current <= '9'); |
772 | | |
773 | 1.06k | exponent += (exponen_sign == '-' ? -num : num); |
774 | 1.06k | } |
775 | | |
776 | 1.18k | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
777 | 0 | return junk_string_value_; |
778 | 0 | } |
779 | 1.18k | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
780 | 0 | return junk_string_value_; |
781 | 0 | } |
782 | 1.18k | if (allow_trailing_spaces) { |
783 | 1.18k | AdvanceToNonspace(¤t, end); |
784 | 1.18k | } |
785 | | |
786 | 2.24k | parsing_done: |
787 | | // insignificant_digits counts integer digits dropped past the significand |
788 | | // limit and is bounded only by the input length, so exponent + it can exceed |
789 | | // int. Saturate: such a value is out of the double range regardless. |
790 | 2.24k | { |
791 | 2.24k | const int64_t combined = |
792 | 2.24k | static_cast<int64_t>(exponent) + insignificant_digits; |
793 | 2.24k | exponent = combined > max_exponent ? max_exponent |
794 | 2.24k | : static_cast<int>(combined); |
795 | 2.24k | } |
796 | | |
797 | 2.24k | if (octal) { |
798 | 220 | double result; |
799 | 220 | bool result_is_junk; |
800 | 220 | char* start = buffer; |
801 | 220 | result = RadixStringToIeee<3>(&start, |
802 | 220 | buffer + buffer_pos, |
803 | 220 | sign, |
804 | 220 | separator_, |
805 | 220 | false, // Don't parse as hex_float. |
806 | 220 | allow_trailing_junk, |
807 | 220 | allow_trailing_spaces, |
808 | 220 | junk_string_value_, |
809 | 220 | read_as_double, |
810 | 220 | &result_is_junk); |
811 | 220 | DOUBLE_CONVERSION_ASSERT(!result_is_junk); |
812 | 220 | *processed_characters_count = static_cast<int>(current - input); |
813 | 220 | return result; |
814 | 220 | } |
815 | | |
816 | 2.02k | if (nonzero_digit_dropped) { |
817 | 28 | buffer[buffer_pos++] = '1'; |
818 | 28 | exponent--; |
819 | 28 | } |
820 | | |
821 | 2.02k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); |
822 | 2.02k | buffer[buffer_pos] = '\0'; |
823 | | |
824 | | // Code above ensures there are no leading zeros and the buffer has fewer than |
825 | | // kMaxSignificantDecimalDigits characters. Trim trailing zeros. |
826 | 2.02k | Vector<const char> chars(buffer, buffer_pos); |
827 | 2.02k | chars = TrimTrailingZeros(chars); |
828 | 2.02k | exponent += buffer_pos - chars.length(); |
829 | | |
830 | 2.02k | double converted; |
831 | 2.02k | if (read_as_double) { |
832 | 2.02k | converted = StrtodTrimmed(chars, exponent); |
833 | 2.02k | } else { |
834 | 0 | converted = StrtofTrimmed(chars, exponent); |
835 | 0 | } |
836 | 2.02k | *processed_characters_count = static_cast<int>(current - input); |
837 | 2.02k | return sign? -converted: converted; |
838 | 2.02k | } double double_conversion::StringToDoubleConverter::StringToIeee<char const*>(char const*, int, bool, int*) const Line | Count | Source | 499 | 3.01k | int* processed_characters_count) const { | 500 | 3.01k | Iterator current = input; | 501 | 3.01k | Iterator end = input + length; | 502 | | | 503 | 3.01k | *processed_characters_count = 0; | 504 | | | 505 | 3.01k | const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; | 506 | 3.01k | const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; | 507 | 3.01k | const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; | 508 | 3.01k | const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; | 509 | 3.01k | const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0; | 510 | | | 511 | | // To make sure that iterator dereferencing is valid the following | 512 | | // convention is used: | 513 | | // 1. Each '++current' statement is followed by check for equality to 'end'. | 514 | | // 2. If AdvanceToNonspace returned false then current == end. | 515 | | // 3. If 'current' becomes equal to 'end' the function returns or goes to | 516 | | // 'parsing_done'. | 517 | | // 4. 'current' is not dereferenced after the 'parsing_done' label. | 518 | | // 5. Code before 'parsing_done' may rely on 'current != end'. | 519 | 3.01k | if (current == end) return empty_string_value_; | 520 | | | 521 | 3.01k | if (allow_leading_spaces || allow_trailing_spaces) { | 522 | 3.01k | if (!AdvanceToNonspace(¤t, end)) { | 523 | 12 | *processed_characters_count = static_cast<int>(current - input); | 524 | 12 | return empty_string_value_; | 525 | 12 | } | 526 | 3.00k | if (!allow_leading_spaces && (input != current)) { | 527 | | // No leading spaces allowed, but AdvanceToNonspace moved forward. | 528 | 0 | return junk_string_value_; | 529 | 0 | } | 530 | 3.00k | } | 531 | | | 532 | | // Exponent will be adjusted if insignificant digits of the integer part | 533 | | // or insignificant leading zeros of the fractional part are dropped. | 534 | 3.00k | int exponent = 0; | 535 | | // Leading fractional zeros and dropped integer digits are both moved into the | 536 | | // exponent, and both are bounded only by the input length. Saturating the | 537 | | // accumulation at this magnitude keeps it inside int; any exponent this large | 538 | | // is far outside the double range, so the clamped result is unchanged. | 539 | 3.00k | const int max_exponent = INT_MAX / 2; | 540 | 3.00k | int significant_digits = 0; | 541 | 3.00k | int insignificant_digits = 0; | 542 | 3.00k | bool nonzero_digit_dropped = false; | 543 | | | 544 | 3.00k | bool sign = false; | 545 | | | 546 | 3.00k | if (*current == '+' || *current == '-') { | 547 | 144 | sign = (*current == '-'); | 548 | 144 | ++current; | 549 | 144 | Iterator next_non_space = current; | 550 | | // Skip following spaces (if allowed). | 551 | 144 | if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; | 552 | 129 | if (!allow_spaces_after_sign && (current != next_non_space)) { | 553 | 0 | return junk_string_value_; | 554 | 0 | } | 555 | 129 | current = next_non_space; | 556 | 129 | } | 557 | | | 558 | 2.98k | if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) { | 559 | 2.98k | if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) { | 560 | 9 | if (!ConsumeSubString(¤t, end, infinity_symbol_, allow_case_insensitivity)) { | 561 | 7 | return junk_string_value_; | 562 | 7 | } | 563 | | | 564 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 565 | 0 | return junk_string_value_; | 566 | 0 | } | 567 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 568 | 0 | return junk_string_value_; | 569 | 0 | } | 570 | | | 571 | 2 | *processed_characters_count = static_cast<int>(current - input); | 572 | 2 | return sign ? -Double::Infinity() : Double::Infinity(); | 573 | 2 | } | 574 | 2.98k | } | 575 | | | 576 | 2.97k | if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) { | 577 | 2.97k | if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) { | 578 | 11 | if (!ConsumeSubString(¤t, end, nan_symbol_, allow_case_insensitivity)) { | 579 | 9 | return junk_string_value_; | 580 | 9 | } | 581 | | | 582 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 583 | 0 | return junk_string_value_; | 584 | 0 | } | 585 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 586 | 0 | return junk_string_value_; | 587 | 0 | } | 588 | | | 589 | 2 | *processed_characters_count = static_cast<int>(current - input); | 590 | 2 | return sign ? -Double::NaN() : Double::NaN(); | 591 | 2 | } | 592 | 2.97k | } | 593 | | | 594 | 2.96k | bool leading_zero = false; | 595 | 2.96k | if (*current == '0') { | 596 | 904 | if (Advance(¤t, separator_, 10, end)) { | 597 | 2 | *processed_characters_count = static_cast<int>(current - input); | 598 | 2 | return SignedZero(sign); | 599 | 2 | } | 600 | | | 601 | 902 | leading_zero = true; | 602 | | | 603 | | // It could be hexadecimal value. | 604 | 902 | if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) && | 605 | 902 | (*current == 'x' || *current == 'X')) { | 606 | 603 | ++current; | 607 | | | 608 | 603 | if (current == end) return junk_string_value_; // "0x" | 609 | | | 610 | 601 | bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && | 611 | 601 | IsHexFloatString(current, end, separator_, allow_trailing_junk, | 612 | 601 | allow_trailing_spaces); | 613 | | | 614 | 601 | if (!parse_as_hex_float && !isDigit(*current, 16)) { | 615 | 77 | return junk_string_value_; | 616 | 77 | } | 617 | | | 618 | 524 | bool result_is_junk; | 619 | 524 | double result = RadixStringToIeee<4>(¤t, | 620 | 524 | end, | 621 | 524 | sign, | 622 | 524 | separator_, | 623 | 524 | parse_as_hex_float, | 624 | 524 | allow_trailing_junk, | 625 | 524 | allow_trailing_spaces, | 626 | 524 | junk_string_value_, | 627 | 524 | read_as_double, | 628 | 524 | &result_is_junk); | 629 | 524 | if (!result_is_junk) { | 630 | 524 | if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); | 631 | 524 | *processed_characters_count = static_cast<int>(current - input); | 632 | 524 | } | 633 | 524 | return result; | 634 | 601 | } | 635 | | | 636 | | // Ignore leading zeros in the integer part. | 637 | 682 | while (*current == '0') { | 638 | 391 | if (Advance(¤t, separator_, 10, end)) { | 639 | 8 | *processed_characters_count = static_cast<int>(current - input); | 640 | 8 | return SignedZero(sign); | 641 | 8 | } | 642 | 391 | } | 643 | 299 | } | 644 | | | 645 | 2.35k | bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0; | 646 | | | 647 | | // The longest form of simplified number is: "-<significant digits>.1eXXX\0". | 648 | 2.35k | const int kBufferSize = kMaxSignificantDigits + 10; | 649 | 2.35k | DOUBLE_CONVERSION_STACK_UNINITIALIZED char | 650 | 2.35k | buffer[kBufferSize]; // NOLINT: size is known at compile time. | 651 | 2.35k | int buffer_pos = 0; | 652 | | | 653 | | // Copy significant digits of the integer part (if any) to the buffer. | 654 | 74.7k | while (*current >= '0' && *current <= '9') { | 655 | 73.2k | if (significant_digits < kMaxSignificantDigits) { | 656 | 72.1k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); | 657 | 72.1k | buffer[buffer_pos++] = static_cast<char>(*current); | 658 | 72.1k | significant_digits++; | 659 | | // Will later check if it's an octal in the buffer. | 660 | 72.1k | } else { | 661 | 1.07k | insignificant_digits++; // Move the digit into the exponential part. | 662 | 1.07k | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; | 663 | 1.07k | } | 664 | 73.2k | octal = octal && *current < '8'; | 665 | 73.2k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; | 666 | 73.2k | } | 667 | | | 668 | 1.59k | if (significant_digits == 0) { | 669 | 311 | octal = false; | 670 | 311 | } | 671 | | | 672 | 1.59k | if (*current == '.') { | 673 | 416 | if (octal && !allow_trailing_junk) return junk_string_value_; | 674 | 416 | if (octal) goto parsing_done; | 675 | | | 676 | 415 | if (Advance(¤t, separator_, 10, end)) { | 677 | 4 | if (significant_digits == 0 && !leading_zero) { | 678 | 2 | return junk_string_value_; | 679 | 2 | } else { | 680 | 2 | goto parsing_done; | 681 | 2 | } | 682 | 4 | } | 683 | | | 684 | 411 | if (significant_digits == 0) { | 685 | | // octal = false; | 686 | | // Integer part consists of 0 or is absent. Significant digits start after | 687 | | // leading zeros (if any). | 688 | 3.99M | while (*current == '0') { | 689 | 3.99M | if (Advance(¤t, separator_, 10, end)) { | 690 | 14 | *processed_characters_count = static_cast<int>(current - input); | 691 | 14 | return SignedZero(sign); | 692 | 14 | } | 693 | | // Saturate to avoid underflow on a pathologically long zero run. | 694 | 3.99M | if (exponent > -(max_exponent / 2)) exponent--; // Move this 0 into the exponent. | 695 | 3.99M | } | 696 | 173 | } | 697 | | | 698 | | // There is a fractional part. | 699 | | // We don't emit a '.', but adjust the exponent instead. | 700 | 69.3k | while (*current >= '0' && *current <= '9') { | 701 | 69.2k | if (significant_digits < kMaxSignificantDigits) { | 702 | 65.4k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); | 703 | 65.4k | buffer[buffer_pos++] = static_cast<char>(*current); | 704 | 65.4k | significant_digits++; | 705 | 65.4k | if (exponent > -(max_exponent / 2)) exponent--; | 706 | 65.4k | } else { | 707 | | // Ignore insignificant digits in the fractional part. | 708 | 3.83k | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; | 709 | 3.83k | } | 710 | 69.2k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; | 711 | 69.2k | } | 712 | 397 | } | 713 | | | 714 | 1.29k | if (!leading_zero && exponent == 0 && significant_digits == 0) { | 715 | | // If leading_zeros is true then the string contains zeros. | 716 | | // If exponent < 0 then string was [+-]\.0*... | 717 | | // If significant_digits != 0 the string is not equal to 0. | 718 | | // Otherwise there are no digits in the string. | 719 | 89 | return junk_string_value_; | 720 | 89 | } | 721 | | | 722 | | // Parse exponential part. | 723 | 1.20k | if (*current == 'e' || *current == 'E') { | 724 | 1.09k | if (octal && !allow_trailing_junk) return junk_string_value_; | 725 | 1.09k | if (octal) goto parsing_done; | 726 | 1.09k | Iterator junk_begin = current; | 727 | 1.09k | ++current; | 728 | 1.09k | if (current == end) { | 729 | 2 | if (allow_trailing_junk) { | 730 | 2 | current = junk_begin; | 731 | 2 | goto parsing_done; | 732 | 2 | } else { | 733 | 0 | return junk_string_value_; | 734 | 0 | } | 735 | 2 | } | 736 | 1.08k | char exponen_sign = '+'; | 737 | 1.08k | if (*current == '+' || *current == '-') { | 738 | 390 | exponen_sign = static_cast<char>(*current); | 739 | 390 | ++current; | 740 | 390 | if (current == end) { | 741 | 2 | if (allow_trailing_junk) { | 742 | 2 | current = junk_begin; | 743 | 2 | goto parsing_done; | 744 | 2 | } else { | 745 | 0 | return junk_string_value_; | 746 | 0 | } | 747 | 2 | } | 748 | 390 | } | 749 | | | 750 | 1.08k | if (current == end || *current < '0' || *current > '9') { | 751 | 22 | if (allow_trailing_junk) { | 752 | 22 | current = junk_begin; | 753 | 22 | goto parsing_done; | 754 | 22 | } else { | 755 | 0 | return junk_string_value_; | 756 | 0 | } | 757 | 22 | } | 758 | | | 759 | 1.06k | DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); | 760 | 1.06k | int num = 0; | 761 | 4.18k | do { | 762 | | // Check overflow. | 763 | 4.18k | int digit = *current - '0'; | 764 | 4.18k | if (num >= max_exponent / 10 | 765 | 396 | && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { | 766 | 393 | num = max_exponent; | 767 | 3.78k | } else { | 768 | 3.78k | num = num * 10 + digit; | 769 | 3.78k | } | 770 | 4.18k | ++current; | 771 | 4.18k | } while (current != end && *current >= '0' && *current <= '9'); | 772 | | | 773 | 1.06k | exponent += (exponen_sign == '-' ? -num : num); | 774 | 1.06k | } | 775 | | | 776 | 1.18k | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 777 | 0 | return junk_string_value_; | 778 | 0 | } | 779 | 1.18k | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 780 | 0 | return junk_string_value_; | 781 | 0 | } | 782 | 1.18k | if (allow_trailing_spaces) { | 783 | 1.18k | AdvanceToNonspace(¤t, end); | 784 | 1.18k | } | 785 | | | 786 | 2.24k | parsing_done: | 787 | | // insignificant_digits counts integer digits dropped past the significand | 788 | | // limit and is bounded only by the input length, so exponent + it can exceed | 789 | | // int. Saturate: such a value is out of the double range regardless. | 790 | 2.24k | { | 791 | 2.24k | const int64_t combined = | 792 | 2.24k | static_cast<int64_t>(exponent) + insignificant_digits; | 793 | 2.24k | exponent = combined > max_exponent ? max_exponent | 794 | 2.24k | : static_cast<int>(combined); | 795 | 2.24k | } | 796 | | | 797 | 2.24k | if (octal) { | 798 | 220 | double result; | 799 | 220 | bool result_is_junk; | 800 | 220 | char* start = buffer; | 801 | 220 | result = RadixStringToIeee<3>(&start, | 802 | 220 | buffer + buffer_pos, | 803 | 220 | sign, | 804 | 220 | separator_, | 805 | 220 | false, // Don't parse as hex_float. | 806 | 220 | allow_trailing_junk, | 807 | 220 | allow_trailing_spaces, | 808 | 220 | junk_string_value_, | 809 | 220 | read_as_double, | 810 | 220 | &result_is_junk); | 811 | 220 | DOUBLE_CONVERSION_ASSERT(!result_is_junk); | 812 | 220 | *processed_characters_count = static_cast<int>(current - input); | 813 | 220 | return result; | 814 | 220 | } | 815 | | | 816 | 2.02k | if (nonzero_digit_dropped) { | 817 | 28 | buffer[buffer_pos++] = '1'; | 818 | 28 | exponent--; | 819 | 28 | } | 820 | | | 821 | 2.02k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); | 822 | 2.02k | buffer[buffer_pos] = '\0'; | 823 | | | 824 | | // Code above ensures there are no leading zeros and the buffer has fewer than | 825 | | // kMaxSignificantDecimalDigits characters. Trim trailing zeros. | 826 | 2.02k | Vector<const char> chars(buffer, buffer_pos); | 827 | 2.02k | chars = TrimTrailingZeros(chars); | 828 | 2.02k | exponent += buffer_pos - chars.length(); | 829 | | | 830 | 2.02k | double converted; | 831 | 2.02k | if (read_as_double) { | 832 | 2.02k | converted = StrtodTrimmed(chars, exponent); | 833 | 2.02k | } else { | 834 | 0 | converted = StrtofTrimmed(chars, exponent); | 835 | 0 | } | 836 | 2.02k | *processed_characters_count = static_cast<int>(current - input); | 837 | 2.02k | return sign? -converted: converted; | 838 | 2.02k | } |
Unexecuted instantiation: double double_conversion::StringToDoubleConverter::StringToIeee<unsigned short const*>(unsigned short const*, int, bool, int*) const |
839 | | |
840 | | |
841 | | double StringToDoubleConverter::StringToDouble( |
842 | | const char* buffer, |
843 | | int length, |
844 | 3.01k | int* processed_characters_count) const { |
845 | 3.01k | return StringToIeee(buffer, length, true, processed_characters_count); |
846 | 3.01k | } |
847 | | |
848 | | |
849 | | double StringToDoubleConverter::StringToDouble( |
850 | | const uc16* buffer, |
851 | | int length, |
852 | 0 | int* processed_characters_count) const { |
853 | 0 | return StringToIeee(buffer, length, true, processed_characters_count); |
854 | 0 | } |
855 | | |
856 | | |
857 | | float StringToDoubleConverter::StringToFloat( |
858 | | const char* buffer, |
859 | | int length, |
860 | 0 | int* processed_characters_count) const { |
861 | 0 | return static_cast<float>(StringToIeee(buffer, length, false, |
862 | 0 | processed_characters_count)); |
863 | 0 | } |
864 | | |
865 | | |
866 | | float StringToDoubleConverter::StringToFloat( |
867 | | const uc16* buffer, |
868 | | int length, |
869 | 0 | int* processed_characters_count) const { |
870 | 0 | return static_cast<float>(StringToIeee(buffer, length, false, |
871 | 0 | processed_characters_count)); |
872 | 0 | } |
873 | | |
874 | | |
875 | | template<> |
876 | | double StringToDoubleConverter::StringTo<double>( |
877 | | const char* buffer, |
878 | | int length, |
879 | 0 | int* processed_characters_count) const { |
880 | 0 | return StringToDouble(buffer, length, processed_characters_count); |
881 | 0 | } |
882 | | |
883 | | |
884 | | template<> |
885 | | float StringToDoubleConverter::StringTo<float>( |
886 | | const char* buffer, |
887 | | int length, |
888 | 0 | int* processed_characters_count) const { |
889 | 0 | return StringToFloat(buffer, length, processed_characters_count); |
890 | 0 | } |
891 | | |
892 | | |
893 | | template<> |
894 | | double StringToDoubleConverter::StringTo<double>( |
895 | | const uc16* buffer, |
896 | | int length, |
897 | 0 | int* processed_characters_count) const { |
898 | 0 | return StringToDouble(buffer, length, processed_characters_count); |
899 | 0 | } |
900 | | |
901 | | |
902 | | template<> |
903 | | float StringToDoubleConverter::StringTo<float>( |
904 | | const uc16* buffer, |
905 | | int length, |
906 | 0 | int* processed_characters_count) const { |
907 | 0 | return StringToFloat(buffer, length, processed_characters_count); |
908 | 0 | } |
909 | | |
910 | | } // namespace double_conversion |