OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 | 112 |
113 void DoubleToStringConverter::CreateDecimalRepresentation( | 113 void DoubleToStringConverter::CreateDecimalRepresentation( |
114 const char* decimal_digits, | 114 const char* decimal_digits, |
115 int length, | 115 int length, |
116 int decimal_point, | 116 int decimal_point, |
117 int digits_after_point, | 117 int digits_after_point, |
118 StringBuilder* result_builder) const { | 118 StringBuilder* result_builder) const { |
119 // Create a representation that is padded with zeros if needed. | 119 // Create a representation that is padded with zeros if needed. |
120 if (decimal_point <= 0) { | 120 if (decimal_point <= 0) { |
121 // "0.00000decimal_rep". | 121 // "0.00000decimal_rep" or "0.000decimal_rep00". |
122 result_builder->AddCharacter('0'); | 122 result_builder->AddCharacter('0'); |
123 if (digits_after_point > 0) { | 123 if (digits_after_point > 0) { |
124 result_builder->AddCharacter('.'); | 124 result_builder->AddCharacter('.'); |
125 result_builder->AddPadding('0', -decimal_point); | 125 result_builder->AddPadding('0', -decimal_point); |
126 ASSERT(length <= digits_after_point - (-decimal_point)); | 126 ASSERT(length <= digits_after_point - (-decimal_point)); |
127 result_builder->AddSubstring(decimal_digits, length); | 127 result_builder->AddSubstring(decimal_digits, length); |
128 int remaining_digits = digits_after_point - (-decimal_point) - length; | 128 int remaining_digits = digits_after_point - (-decimal_point) - length; |
129 result_builder->AddPadding('0', remaining_digits); | 129 result_builder->AddPadding('0', remaining_digits); |
130 } | 130 } |
131 } else if (decimal_point >= length) { | 131 } else if (decimal_point >= length) { |
132 // "decimal_rep0000.00000" or "decimal_rep.0000" | 132 // "decimal_rep0000.00000" or "decimal_rep.0000". |
133 result_builder->AddSubstring(decimal_digits, length); | 133 result_builder->AddSubstring(decimal_digits, length); |
134 result_builder->AddPadding('0', decimal_point - length); | 134 result_builder->AddPadding('0', decimal_point - length); |
135 if (digits_after_point > 0) { | 135 if (digits_after_point > 0) { |
136 result_builder->AddCharacter('.'); | 136 result_builder->AddCharacter('.'); |
137 result_builder->AddPadding('0', digits_after_point); | 137 result_builder->AddPadding('0', digits_after_point); |
138 } | 138 } |
139 } else { | 139 } else { |
140 // "decima.l_rep000" | 140 // "decima.l_rep000". |
141 ASSERT(digits_after_point > 0); | 141 ASSERT(digits_after_point > 0); |
142 result_builder->AddSubstring(decimal_digits, decimal_point); | 142 result_builder->AddSubstring(decimal_digits, decimal_point); |
143 result_builder->AddCharacter('.'); | 143 result_builder->AddCharacter('.'); |
144 ASSERT(length - decimal_point <= digits_after_point); | 144 ASSERT(length - decimal_point <= digits_after_point); |
145 result_builder->AddSubstring(&decimal_digits[decimal_point], | 145 result_builder->AddSubstring(&decimal_digits[decimal_point], |
146 length - decimal_point); | 146 length - decimal_point); |
147 int remaining_digits = digits_after_point - (length - decimal_point); | 147 int remaining_digits = digits_after_point - (length - decimal_point); |
148 result_builder->AddPadding('0', remaining_digits); | 148 result_builder->AddPadding('0', remaining_digits); |
149 } | 149 } |
150 if (digits_after_point == 0) { | 150 if (digits_after_point == 0) { |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 409 |
410 // If the fast dtoa didn't succeed use the slower bignum version. | 410 // If the fast dtoa didn't succeed use the slower bignum version. |
411 BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); | 411 BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); |
412 BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); | 412 BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); |
413 vector[*length] = '\0'; | 413 vector[*length] = '\0'; |
414 } | 414 } |
415 | 415 |
416 | 416 |
417 // Consumes the given substring from the iterator. | 417 // Consumes the given substring from the iterator. |
418 // Returns false, if the substring does not match. | 418 // Returns false, if the substring does not match. |
419 static bool ConsumeSubString(const char** current, | 419 template <class Iterator> |
420 const char* end, | 420 static bool ConsumeSubString(Iterator* current, |
| 421 Iterator end, |
421 const char* substring) { | 422 const char* substring) { |
422 ASSERT(**current == *substring); | 423 ASSERT(**current == *substring); |
423 for (substring++; *substring != '\0'; substring++) { | 424 for (substring++; *substring != '\0'; substring++) { |
424 ++*current; | 425 ++*current; |
425 if (*current == end || **current != *substring) return false; | 426 if (*current == end || **current != *substring) return false; |
426 } | 427 } |
427 ++*current; | 428 ++*current; |
428 return true; | 429 return true; |
429 } | 430 } |
430 | 431 |
431 | 432 |
432 // Maximum number of significant digits in decimal representation. | 433 // Maximum number of significant digits in decimal representation. |
433 // The longest possible double in decimal representation is | 434 // The longest possible double in decimal representation is |
434 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 | 435 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 |
435 // (768 digits). If we parse a number whose first digits are equal to a | 436 // (768 digits). If we parse a number whose first digits are equal to a |
436 // mean of 2 adjacent doubles (that could have up to 769 digits) the result | 437 // mean of 2 adjacent doubles (that could have up to 769 digits) the result |
437 // must be rounded to the bigger one unless the tail consists of zeros, so | 438 // must be rounded to the bigger one unless the tail consists of zeros, so |
438 // we don't need to preserve all the digits. | 439 // we don't need to preserve all the digits. |
439 const int kMaxSignificantDigits = 772; | 440 const int kMaxSignificantDigits = 772; |
440 | 441 |
441 | 442 |
| 443 static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 }; |
| 444 static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7); |
| 445 |
| 446 |
| 447 static const uc16 kWhitespaceTable16[] = { |
| 448 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, |
| 449 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 |
| 450 }; |
| 451 static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16); |
| 452 |
| 453 |
| 454 static bool isWhitespace(int x) { |
| 455 if (x < 128) { |
| 456 for (int i = 0; i < kWhitespaceTable7Length; i++) { |
| 457 if (kWhitespaceTable7[i] == x) return true; |
| 458 } |
| 459 } else { |
| 460 for (int i = 0; i < kWhitespaceTable16Length; i++) { |
| 461 if (kWhitespaceTable16[i] == x) return true; |
| 462 } |
| 463 } |
| 464 return false; |
| 465 } |
| 466 |
| 467 |
442 // Returns true if a nonspace found and false if the end has reached. | 468 // Returns true if a nonspace found and false if the end has reached. |
443 static inline bool AdvanceToNonspace(const char** current, const char* end) { | 469 template <class Iterator> |
| 470 static inline bool AdvanceToNonspace(Iterator* current, Iterator end) { |
444 while (*current != end) { | 471 while (*current != end) { |
445 if (**current != ' ') return true; | 472 if (!isWhitespace(**current)) return true; |
446 ++*current; | 473 ++*current; |
447 } | 474 } |
448 return false; | 475 return false; |
449 } | 476 } |
450 | 477 |
451 | 478 |
452 static bool isDigit(int x, int radix) { | 479 static bool isDigit(int x, int radix) { |
453 return (x >= '0' && x <= '9' && x < '0' + radix) | 480 return (x >= '0' && x <= '9' && x < '0' + radix) |
454 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) | 481 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
455 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); | 482 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
456 } | 483 } |
457 | 484 |
458 | 485 |
459 static double SignedZero(bool sign) { | 486 static double SignedZero(bool sign) { |
460 return sign ? -0.0 : 0.0; | 487 return sign ? -0.0 : 0.0; |
461 } | 488 } |
462 | 489 |
463 | 490 |
464 // Returns true if 'c' is a decimal digit that is valid for the given radix. | 491 // Returns true if 'c' is a decimal digit that is valid for the given radix. |
465 // | 492 // |
466 // The function is small and could be inlined, but VS2012 emitted a warning | 493 // The function is small and could be inlined, but VS2012 emitted a warning |
467 // because it constant-propagated the radix and concluded that the last | 494 // because it constant-propagated the radix and concluded that the last |
468 // condition was always true. By moving it into a separate function the | 495 // condition was always true. By moving it into a separate function the |
469 // compiler wouldn't warn anymore. | 496 // compiler wouldn't warn anymore. |
| 497 #if _MSC_VER |
| 498 #pragma optimize("",off) |
470 static bool IsDecimalDigitForRadix(int c, int radix) { | 499 static bool IsDecimalDigitForRadix(int c, int radix) { |
471 return '0' <= c && c <= '9' && (c - '0') < radix; | 500 return '0' <= c && c <= '9' && (c - '0') < radix; |
472 } | 501 } |
473 | 502 #pragma optimize("",on) |
| 503 #else |
| 504 static bool inline IsDecimalDigitForRadix(int c, int radix) { |
| 505 » return '0' <= c && c <= '9' && (c - '0') < radix; |
| 506 } |
| 507 #endif |
474 // Returns true if 'c' is a character digit that is valid for the given radix. | 508 // Returns true if 'c' is a character digit that is valid for the given radix. |
475 // The 'a_character' should be 'a' or 'A'. | 509 // The 'a_character' should be 'a' or 'A'. |
476 // | 510 // |
477 // The function is small and could be inlined, but VS2012 emitted a warning | 511 // The function is small and could be inlined, but VS2012 emitted a warning |
478 // because it constant-propagated the radix and concluded that the first | 512 // because it constant-propagated the radix and concluded that the first |
479 // condition was always false. By moving it into a separate function the | 513 // condition was always false. By moving it into a separate function the |
480 // compiler wouldn't warn anymore. | 514 // compiler wouldn't warn anymore. |
481 static bool IsCharacterDigitForRadix(int c, int radix, char a_character) { | 515 static bool IsCharacterDigitForRadix(int c, int radix, char a_character) { |
482 return radix > 10 && c >= a_character && c < a_character + radix - 10; | 516 return radix > 10 && c >= a_character && c < a_character + radix - 10; |
483 } | 517 } |
484 | 518 |
485 | 519 |
486 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. | 520 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
487 template <int radix_log_2> | 521 template <int radix_log_2, class Iterator> |
488 static double RadixStringToIeee(const char* current, | 522 static double RadixStringToIeee(Iterator* current, |
489 const char* end, | 523 Iterator end, |
490 bool sign, | 524 bool sign, |
491 bool allow_trailing_junk, | 525 bool allow_trailing_junk, |
492 double junk_string_value, | 526 double junk_string_value, |
493 bool read_as_double, | 527 bool read_as_double, |
494 const char** trailing_pointer) { | 528 bool* result_is_junk) { |
495 ASSERT(current != end); | 529 ASSERT(*current != end); |
496 | 530 |
497 const int kDoubleSize = Double::kSignificandSize; | 531 const int kDoubleSize = Double::kSignificandSize; |
498 const int kSingleSize = Single::kSignificandSize; | 532 const int kSingleSize = Single::kSignificandSize; |
499 const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize; | 533 const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize; |
500 | 534 |
| 535 *result_is_junk = true; |
| 536 |
501 // Skip leading 0s. | 537 // Skip leading 0s. |
502 while (*current == '0') { | 538 while (**current == '0') { |
503 ++current; | 539 ++(*current); |
504 if (current == end) { | 540 if (*current == end) { |
505 *trailing_pointer = end; | 541 *result_is_junk = false; |
506 return SignedZero(sign); | 542 return SignedZero(sign); |
507 } | 543 } |
508 } | 544 } |
509 | 545 |
510 int64_t number = 0; | 546 int64_t number = 0; |
511 int exponent = 0; | 547 int exponent = 0; |
512 const int radix = (1 << radix_log_2); | 548 const int radix = (1 << radix_log_2); |
513 | 549 |
514 do { | 550 do { |
515 int digit; | 551 int digit; |
516 if (IsDecimalDigitForRadix(*current, radix)) { | 552 if (IsDecimalDigitForRadix(**current, radix)) { |
517 digit = static_cast<char>(*current) - '0'; | 553 digit = static_cast<char>(**current) - '0'; |
518 } else if (IsCharacterDigitForRadix(*current, radix, 'a')) { | 554 } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { |
519 digit = static_cast<char>(*current) - 'a' + 10; | 555 digit = static_cast<char>(**current) - 'a' + 10; |
520 } else if (IsCharacterDigitForRadix(*current, radix, 'A')) { | 556 } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { |
521 digit = static_cast<char>(*current) - 'A' + 10; | 557 digit = static_cast<char>(**current) - 'A' + 10; |
522 } else { | 558 } else { |
523 if (allow_trailing_junk || !AdvanceToNonspace(¤t, end)) { | 559 if (allow_trailing_junk || !AdvanceToNonspace(current, end)) { |
524 break; | 560 break; |
525 } else { | 561 } else { |
526 return junk_string_value; | 562 return junk_string_value; |
527 } | 563 } |
528 } | 564 } |
529 | 565 |
530 number = number * radix + digit; | 566 number = number * radix + digit; |
531 int overflow = static_cast<int>(number >> kSignificandSize); | 567 int overflow = static_cast<int>(number >> kSignificandSize); |
532 if (overflow != 0) { | 568 if (overflow != 0) { |
533 // Overflow occurred. Need to determine which direction to round the | 569 // Overflow occurred. Need to determine which direction to round the |
534 // result. | 570 // result. |
535 int overflow_bits_count = 1; | 571 int overflow_bits_count = 1; |
536 while (overflow > 1) { | 572 while (overflow > 1) { |
537 overflow_bits_count++; | 573 overflow_bits_count++; |
538 overflow >>= 1; | 574 overflow >>= 1; |
539 } | 575 } |
540 | 576 |
541 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 577 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); |
542 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 578 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; |
543 number >>= overflow_bits_count; | 579 number >>= overflow_bits_count; |
544 exponent = overflow_bits_count; | 580 exponent = overflow_bits_count; |
545 | 581 |
546 bool zero_tail = true; | 582 bool zero_tail = true; |
547 for (;;) { | 583 for (;;) { |
548 ++current; | 584 ++(*current); |
549 if (current == end || !isDigit(*current, radix)) break; | 585 if (*current == end || !isDigit(**current, radix)) break; |
550 zero_tail = zero_tail && *current == '0'; | 586 zero_tail = zero_tail && **current == '0'; |
551 exponent += radix_log_2; | 587 exponent += radix_log_2; |
552 } | 588 } |
553 | 589 |
554 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 590 if (!allow_trailing_junk && AdvanceToNonspace(current, end)) { |
555 return junk_string_value; | 591 return junk_string_value; |
556 } | 592 } |
557 | 593 |
558 int middle_value = (1 << (overflow_bits_count - 1)); | 594 int middle_value = (1 << (overflow_bits_count - 1)); |
559 if (dropped_bits > middle_value) { | 595 if (dropped_bits > middle_value) { |
560 number++; // Rounding up. | 596 number++; // Rounding up. |
561 } else if (dropped_bits == middle_value) { | 597 } else if (dropped_bits == middle_value) { |
562 // Rounding to even to consistency with decimals: half-way case rounds | 598 // Rounding to even to consistency with decimals: half-way case rounds |
563 // up if significant part is odd and down otherwise. | 599 // up if significant part is odd and down otherwise. |
564 if ((number & 1) != 0 || !zero_tail) { | 600 if ((number & 1) != 0 || !zero_tail) { |
565 number++; // Rounding up. | 601 number++; // Rounding up. |
566 } | 602 } |
567 } | 603 } |
568 | 604 |
569 // Rounding up may cause overflow. | 605 // Rounding up may cause overflow. |
570 if ((number & ((int64_t)1 << kSignificandSize)) != 0) { | 606 if ((number & ((int64_t)1 << kSignificandSize)) != 0) { |
571 exponent++; | 607 exponent++; |
572 number >>= 1; | 608 number >>= 1; |
573 } | 609 } |
574 break; | 610 break; |
575 } | 611 } |
576 ++current; | 612 ++(*current); |
577 } while (current != end); | 613 } while (*current != end); |
578 | 614 |
579 ASSERT(number < ((int64_t)1 << kSignificandSize)); | 615 ASSERT(number < ((int64_t)1 << kSignificandSize)); |
580 const double double_number = static_cast<double>(number); | 616 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); |
581 ASSERT(static_cast<int64_t>(double_number) == number); | |
582 | 617 |
583 *trailing_pointer = current; | 618 *result_is_junk = false; |
584 | 619 |
585 if (exponent == 0) { | 620 if (exponent == 0) { |
586 if (sign) { | 621 if (sign) { |
587 if (number == 0) return -0.0; | 622 if (number == 0) return -0.0; |
588 number = -number; | 623 number = -number; |
589 } | 624 } |
590 return static_cast<double>(number); | 625 return static_cast<double>(number); |
591 } | 626 } |
592 | 627 |
593 ASSERT(number != 0); | 628 ASSERT(number != 0); |
594 return Double(DiyFp(number, exponent)).value(); | 629 return Double(DiyFp(number, exponent)).value(); |
595 } | 630 } |
596 | 631 |
597 | 632 |
| 633 template <class Iterator> |
598 double StringToDoubleConverter::StringToIeee( | 634 double StringToDoubleConverter::StringToIeee( |
599 const char* input, | 635 Iterator input, |
600 int length, | 636 int length, |
601 int* processed_characters_count, | 637 bool read_as_double, |
602 bool read_as_double) const { | 638 int* processed_characters_count) const { |
603 const char* current = input; | 639 Iterator current = input; |
604 const char* end = input + length; | 640 Iterator end = input + length; |
605 | 641 |
606 *processed_characters_count = 0; | 642 *processed_characters_count = 0; |
607 | 643 |
608 const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; | 644 const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; |
609 const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; | 645 const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; |
610 const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; | 646 const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; |
611 const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; | 647 const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; |
612 | 648 |
613 // To make sure that iterator dereferencing is valid the following | 649 // To make sure that iterator dereferencing is valid the following |
614 // convention is used: | 650 // convention is used: |
(...skipping 26 matching lines...) Expand all Loading... |
641 int exponent = 0; | 677 int exponent = 0; |
642 int significant_digits = 0; | 678 int significant_digits = 0; |
643 int insignificant_digits = 0; | 679 int insignificant_digits = 0; |
644 bool nonzero_digit_dropped = false; | 680 bool nonzero_digit_dropped = false; |
645 | 681 |
646 bool sign = false; | 682 bool sign = false; |
647 | 683 |
648 if (*current == '+' || *current == '-') { | 684 if (*current == '+' || *current == '-') { |
649 sign = (*current == '-'); | 685 sign = (*current == '-'); |
650 ++current; | 686 ++current; |
651 const char* next_non_space = current; | 687 Iterator next_non_space = current; |
652 // Skip following spaces (if allowed). | 688 // Skip following spaces (if allowed). |
653 if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; | 689 if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; |
654 if (!allow_spaces_after_sign && (current != next_non_space)) { | 690 if (!allow_spaces_after_sign && (current != next_non_space)) { |
655 return junk_string_value_; | 691 return junk_string_value_; |
656 } | 692 } |
657 current = next_non_space; | 693 current = next_non_space; |
658 } | 694 } |
659 | 695 |
660 if (infinity_symbol_ != NULL) { | 696 if (infinity_symbol_ != NULL) { |
661 if (*current == infinity_symbol_[0]) { | 697 if (*current == infinity_symbol_[0]) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 | 741 |
706 leading_zero = true; | 742 leading_zero = true; |
707 | 743 |
708 // It could be hexadecimal value. | 744 // It could be hexadecimal value. |
709 if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 745 if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
710 ++current; | 746 ++current; |
711 if (current == end || !isDigit(*current, 16)) { | 747 if (current == end || !isDigit(*current, 16)) { |
712 return junk_string_value_; // "0x". | 748 return junk_string_value_; // "0x". |
713 } | 749 } |
714 | 750 |
715 const char* tail_pointer = NULL; | 751 bool result_is_junk; |
716 double result = RadixStringToIeee<4>(current, | 752 double result = RadixStringToIeee<4>(¤t, |
717 end, | 753 end, |
718 sign, | 754 sign, |
719 allow_trailing_junk, | 755 allow_trailing_junk, |
720 junk_string_value_, | 756 junk_string_value_, |
721 read_as_double, | 757 read_as_double, |
722 &tail_pointer); | 758 &result_is_junk); |
723 if (tail_pointer != NULL) { | 759 if (!result_is_junk) { |
724 if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end); | 760 if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); |
725 *processed_characters_count = static_cast<int>(tail_pointer - input); | 761 *processed_characters_count = static_cast<int>(current - input); |
726 } | 762 } |
727 return result; | 763 return result; |
728 } | 764 } |
729 | 765 |
730 // Ignore leading zeros in the integer part. | 766 // Ignore leading zeros in the integer part. |
731 while (*current == '0') { | 767 while (*current == '0') { |
732 ++current; | 768 ++current; |
733 if (current == end) { | 769 if (current == end) { |
734 *processed_characters_count = static_cast<int>(current - input); | 770 *processed_characters_count = static_cast<int>(current - input); |
735 return SignedZero(sign); | 771 return SignedZero(sign); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 if (octal && !allow_trailing_junk) return junk_string_value_; | 852 if (octal && !allow_trailing_junk) return junk_string_value_; |
817 if (octal) goto parsing_done; | 853 if (octal) goto parsing_done; |
818 ++current; | 854 ++current; |
819 if (current == end) { | 855 if (current == end) { |
820 if (allow_trailing_junk) { | 856 if (allow_trailing_junk) { |
821 goto parsing_done; | 857 goto parsing_done; |
822 } else { | 858 } else { |
823 return junk_string_value_; | 859 return junk_string_value_; |
824 } | 860 } |
825 } | 861 } |
826 char sign = '+'; | 862 char exponen_sign = '+'; |
827 if (*current == '+' || *current == '-') { | 863 if (*current == '+' || *current == '-') { |
828 sign = static_cast<char>(*current); | 864 exponen_sign = static_cast<char>(*current); |
829 ++current; | 865 ++current; |
830 if (current == end) { | 866 if (current == end) { |
831 if (allow_trailing_junk) { | 867 if (allow_trailing_junk) { |
832 goto parsing_done; | 868 goto parsing_done; |
833 } else { | 869 } else { |
834 return junk_string_value_; | 870 return junk_string_value_; |
835 } | 871 } |
836 } | 872 } |
837 } | 873 } |
838 | 874 |
(...skipping 13 matching lines...) Expand all Loading... |
852 int digit = *current - '0'; | 888 int digit = *current - '0'; |
853 if (num >= max_exponent / 10 | 889 if (num >= max_exponent / 10 |
854 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { | 890 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { |
855 num = max_exponent; | 891 num = max_exponent; |
856 } else { | 892 } else { |
857 num = num * 10 + digit; | 893 num = num * 10 + digit; |
858 } | 894 } |
859 ++current; | 895 ++current; |
860 } while (current != end && *current >= '0' && *current <= '9'); | 896 } while (current != end && *current >= '0' && *current <= '9'); |
861 | 897 |
862 exponent += (sign == '-' ? -num : num); | 898 exponent += (exponen_sign == '-' ? -num : num); |
863 } | 899 } |
864 | 900 |
865 if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 901 if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
866 return junk_string_value_; | 902 return junk_string_value_; |
867 } | 903 } |
868 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 904 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
869 return junk_string_value_; | 905 return junk_string_value_; |
870 } | 906 } |
871 if (allow_trailing_spaces) { | 907 if (allow_trailing_spaces) { |
872 AdvanceToNonspace(¤t, end); | 908 AdvanceToNonspace(¤t, end); |
873 } | 909 } |
874 | 910 |
875 parsing_done: | 911 parsing_done: |
876 exponent += insignificant_digits; | 912 exponent += insignificant_digits; |
877 | 913 |
878 if (octal) { | 914 if (octal) { |
879 double result; | 915 double result; |
880 const char* tail_pointer = NULL; | 916 bool result_is_junk; |
881 result = RadixStringToIeee<3>(buffer, | 917 char* start = buffer; |
| 918 result = RadixStringToIeee<3>(&start, |
882 buffer + buffer_pos, | 919 buffer + buffer_pos, |
883 sign, | 920 sign, |
884 allow_trailing_junk, | 921 allow_trailing_junk, |
885 junk_string_value_, | 922 junk_string_value_, |
886 read_as_double, | 923 read_as_double, |
887 &tail_pointer); | 924 &result_is_junk); |
888 ASSERT(tail_pointer != NULL); | 925 ASSERT(!result_is_junk); |
889 *processed_characters_count = static_cast<int>(current - input); | 926 *processed_characters_count = static_cast<int>(current - input); |
890 return result; | 927 return result; |
891 } | 928 } |
892 | 929 |
893 if (nonzero_digit_dropped) { | 930 if (nonzero_digit_dropped) { |
894 buffer[buffer_pos++] = '1'; | 931 buffer[buffer_pos++] = '1'; |
895 exponent--; | 932 exponent--; |
896 } | 933 } |
897 | 934 |
898 ASSERT(buffer_pos < kBufferSize); | 935 ASSERT(buffer_pos < kBufferSize); |
899 buffer[buffer_pos] = '\0'; | 936 buffer[buffer_pos] = '\0'; |
900 | 937 |
901 double converted; | 938 double converted; |
902 if (read_as_double) { | 939 if (read_as_double) { |
903 converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 940 converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
904 } else { | 941 } else { |
905 converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent); | 942 converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent); |
906 } | 943 } |
907 *processed_characters_count = static_cast<int>(current - input); | 944 *processed_characters_count = static_cast<int>(current - input); |
908 return sign? -converted: converted; | 945 return sign? -converted: converted; |
909 } | 946 } |
910 | 947 |
| 948 |
| 949 double StringToDoubleConverter::StringToDouble( |
| 950 const char* buffer, |
| 951 int length, |
| 952 int* processed_characters_count) const { |
| 953 return StringToIeee(buffer, length, true, processed_characters_count); |
| 954 } |
| 955 |
| 956 |
| 957 double StringToDoubleConverter::StringToDouble( |
| 958 const uc16* buffer, |
| 959 int length, |
| 960 int* processed_characters_count) const { |
| 961 return StringToIeee(buffer, length, true, processed_characters_count); |
| 962 } |
| 963 |
| 964 |
| 965 float StringToDoubleConverter::StringToFloat( |
| 966 const char* buffer, |
| 967 int length, |
| 968 int* processed_characters_count) const { |
| 969 return static_cast<float>(StringToIeee(buffer, length, false, |
| 970 processed_characters_count)); |
| 971 } |
| 972 |
| 973 |
| 974 float StringToDoubleConverter::StringToFloat( |
| 975 const uc16* buffer, |
| 976 int length, |
| 977 int* processed_characters_count) const { |
| 978 return static_cast<float>(StringToIeee(buffer, length, false, |
| 979 processed_characters_count)); |
| 980 } |
| 981 |
911 } // namespace double_conversion | 982 } // namespace double_conversion |
OLD | NEW |