| 670 | } |
| 671 | |
| 672 | static void AdjustIntegerStringWithScale(int32_t scale, std::string* str) { |
| 673 | if (scale == 0) { |
| 674 | return; |
| 675 | } |
| 676 | DCHECK(str != nullptr); |
| 677 | DCHECK(!str->empty()); |
| 678 | const bool is_negative = str->front() == '-'; |
| 679 | const auto is_negative_offset = static_cast<int32_t>(is_negative); |
| 680 | const auto len = static_cast<int32_t>(str->size()); |
| 681 | const int32_t num_digits = len - is_negative_offset; |
| 682 | const int32_t adjusted_exponent = num_digits - 1 - scale; |
| 683 | |
| 684 | /// Note that the -6 is taken from the Java BigDecimal documentation. |
| 685 | if (scale < 0 || adjusted_exponent < -6) { |
| 686 | // Example 1: |
| 687 | // Precondition: *str = "123", is_negative_offset = 0, num_digits = 3, scale = -2, |
| 688 | // adjusted_exponent = 4 |
| 689 | // After inserting decimal point: *str = "1.23" |
| 690 | // After appending exponent: *str = "1.23E+4" |
| 691 | // Example 2: |
| 692 | // Precondition: *str = "-123", is_negative_offset = 1, num_digits = 3, scale = 9, |
| 693 | // adjusted_exponent = -7 |
| 694 | // After inserting decimal point: *str = "-1.23" |
| 695 | // After appending exponent: *str = "-1.23E-7" |
| 696 | // Example 3: |
| 697 | // Precondition: *str = "0", is_negative_offset = 0, num_digits = 1, scale = -1, |
| 698 | // adjusted_exponent = 1 |
| 699 | // After inserting decimal point: *str = "0" // Not inserted |
| 700 | // After appending exponent: *str = "0E+1" |
| 701 | if (num_digits > 1) { |
| 702 | str->insert(str->begin() + 1 + is_negative_offset, '.'); |
| 703 | } |
| 704 | str->push_back('E'); |
| 705 | if (adjusted_exponent >= 0) { |
| 706 | str->push_back('+'); |
| 707 | } |
| 708 | internal::StringFormatter<Int32Type> format; |
| 709 | format(adjusted_exponent, [str](std::string_view formatted) { |
| 710 | str->append(formatted.data(), formatted.size()); |
| 711 | }); |
| 712 | return; |
| 713 | } |
| 714 | |
| 715 | if (num_digits > scale) { |
| 716 | const auto n = static_cast<size_t>(len - scale); |
| 717 | // Example 1: |
| 718 | // Precondition: *str = "123", len = num_digits = 3, scale = 1, n = 2 |
| 719 | // After inserting decimal point: *str = "12.3" |
| 720 | // Example 2: |
| 721 | // Precondition: *str = "-123", len = 4, num_digits = 3, scale = 1, n = 3 |
| 722 | // After inserting decimal point: *str = "-12.3" |
| 723 | str->insert(str->begin() + n, '.'); |
| 724 | return; |
| 725 | } |
| 726 | |
| 727 | // Example 1: |
| 728 | // Precondition: *str = "123", is_negative_offset = 0, num_digits = 3, scale = 4 |
| 729 | // After insert: *str = "000123" |