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