Index: src/conversions.cc |
diff --git a/src/conversions.cc b/src/conversions.cc |
index 353b6810f5ba8e474223966eadbe7bf7d31d8d74..232eda08c933cf7bf6418e58edf1a0c2e66ee2c2 100644 |
--- a/src/conversions.cc |
+++ b/src/conversions.cc |
@@ -28,693 +28,15 @@ |
#include <stdarg.h> |
#include <limits.h> |
-#include "v8.h" |
- |
#include "conversions-inl.h" |
#include "dtoa.h" |
-#include "factory.h" |
#include "scanner-base.h" |
#include "strtod.h" |
+#include "utils.h" |
namespace v8 { |
namespace internal { |
-namespace { |
- |
-// C++-style iterator adaptor for StringInputBuffer |
-// (unlike C++ iterators the end-marker has different type). |
-class StringInputBufferIterator { |
- public: |
- class EndMarker {}; |
- |
- explicit StringInputBufferIterator(StringInputBuffer* buffer); |
- |
- int operator*() const; |
- void operator++(); |
- bool operator==(EndMarker const&) const { return end_; } |
- bool operator!=(EndMarker const& m) const { return !end_; } |
- |
- private: |
- StringInputBuffer* const buffer_; |
- int current_; |
- bool end_; |
-}; |
- |
- |
-StringInputBufferIterator::StringInputBufferIterator( |
- StringInputBuffer* buffer) : buffer_(buffer) { |
- ++(*this); |
-} |
- |
-int StringInputBufferIterator::operator*() const { |
- return current_; |
-} |
- |
- |
-void StringInputBufferIterator::operator++() { |
- end_ = !buffer_->has_more(); |
- if (!end_) { |
- current_ = buffer_->GetNext(); |
- } |
-} |
-} |
- |
- |
-template <class Iterator, class EndMark> |
-static bool SubStringEquals(Iterator* current, |
- EndMark end, |
- const char* substring) { |
- ASSERT(**current == *substring); |
- for (substring++; *substring != '\0'; substring++) { |
- ++*current; |
- if (*current == end || **current != *substring) return false; |
- } |
- ++*current; |
- return true; |
-} |
- |
- |
-// Maximum number of significant digits in decimal representation. |
-// The longest possible double in decimal representation is |
-// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 |
-// (768 digits). If we parse a number whose first digits are equal to a |
-// mean of 2 adjacent doubles (that could have up to 769 digits) the result |
-// must be rounded to the bigger one unless the tail consists of zeros, so |
-// we don't need to preserve all the digits. |
-const int kMaxSignificantDigits = 772; |
- |
- |
-static const double JUNK_STRING_VALUE = OS::nan_value(); |
- |
- |
-// Returns true if a nonspace found and false if the end has reached. |
-template <class Iterator, class EndMark> |
-static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache, |
- Iterator* current, |
- EndMark end) { |
- while (*current != end) { |
- if (!unicode_cache->IsWhiteSpace(**current)) return true; |
- ++*current; |
- } |
- return false; |
-} |
- |
- |
-static bool isDigit(int x, int radix) { |
- return (x >= '0' && x <= '9' && x < '0' + radix) |
- || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
- || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
-} |
- |
- |
-static double SignedZero(bool negative) { |
- return negative ? -0.0 : 0.0; |
-} |
- |
- |
-// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
-template <int radix_log_2, class Iterator, class EndMark> |
-static double InternalStringToIntDouble(UnicodeCache* unicode_cache, |
- Iterator current, |
- EndMark end, |
- bool negative, |
- bool allow_trailing_junk) { |
- ASSERT(current != end); |
- |
- // Skip leading 0s. |
- while (*current == '0') { |
- ++current; |
- if (current == end) return SignedZero(negative); |
- } |
- |
- int64_t number = 0; |
- int exponent = 0; |
- const int radix = (1 << radix_log_2); |
- |
- do { |
- int digit; |
- if (*current >= '0' && *current <= '9' && *current < '0' + radix) { |
- digit = static_cast<char>(*current) - '0'; |
- } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { |
- digit = static_cast<char>(*current) - 'a' + 10; |
- } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { |
- digit = static_cast<char>(*current) - 'A' + 10; |
- } else { |
- if (allow_trailing_junk || |
- !AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- break; |
- } else { |
- return JUNK_STRING_VALUE; |
- } |
- } |
- |
- number = number * radix + digit; |
- int overflow = static_cast<int>(number >> 53); |
- if (overflow != 0) { |
- // Overflow occurred. Need to determine which direction to round the |
- // result. |
- int overflow_bits_count = 1; |
- while (overflow > 1) { |
- overflow_bits_count++; |
- overflow >>= 1; |
- } |
- |
- int dropped_bits_mask = ((1 << overflow_bits_count) - 1); |
- int dropped_bits = static_cast<int>(number) & dropped_bits_mask; |
- number >>= overflow_bits_count; |
- exponent = overflow_bits_count; |
- |
- bool zero_tail = true; |
- while (true) { |
- ++current; |
- if (current == end || !isDigit(*current, radix)) break; |
- zero_tail = zero_tail && *current == '0'; |
- exponent += radix_log_2; |
- } |
- |
- if (!allow_trailing_junk && |
- AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- int middle_value = (1 << (overflow_bits_count - 1)); |
- if (dropped_bits > middle_value) { |
- number++; // Rounding up. |
- } else if (dropped_bits == middle_value) { |
- // Rounding to even to consistency with decimals: half-way case rounds |
- // up if significant part is odd and down otherwise. |
- if ((number & 1) != 0 || !zero_tail) { |
- number++; // Rounding up. |
- } |
- } |
- |
- // Rounding up may cause overflow. |
- if ((number & ((int64_t)1 << 53)) != 0) { |
- exponent++; |
- number >>= 1; |
- } |
- break; |
- } |
- ++current; |
- } while (current != end); |
- |
- ASSERT(number < ((int64_t)1 << 53)); |
- ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); |
- |
- if (exponent == 0) { |
- if (negative) { |
- if (number == 0) return -0.0; |
- number = -number; |
- } |
- return static_cast<double>(number); |
- } |
- |
- ASSERT(number != 0); |
- // The double could be constructed faster from number (mantissa), exponent |
- // and sign. Assuming it's a rare case more simple code is used. |
- return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); |
-} |
- |
- |
-template <class Iterator, class EndMark> |
-static double InternalStringToInt(UnicodeCache* unicode_cache, |
- Iterator current, |
- EndMark end, |
- int radix) { |
- const bool allow_trailing_junk = true; |
- const double empty_string_val = JUNK_STRING_VALUE; |
- |
- if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return empty_string_val; |
- } |
- |
- bool negative = false; |
- bool leading_zero = false; |
- |
- if (*current == '+') { |
- // Ignore leading sign; skip following spaces. |
- ++current; |
- if (current == end) { |
- return JUNK_STRING_VALUE; |
- } |
- } else if (*current == '-') { |
- ++current; |
- if (current == end) { |
- return JUNK_STRING_VALUE; |
- } |
- negative = true; |
- } |
- |
- if (radix == 0) { |
- // Radix detection. |
- if (*current == '0') { |
- ++current; |
- if (current == end) return SignedZero(negative); |
- if (*current == 'x' || *current == 'X') { |
- radix = 16; |
- ++current; |
- if (current == end) return JUNK_STRING_VALUE; |
- } else { |
- radix = 8; |
- leading_zero = true; |
- } |
- } else { |
- radix = 10; |
- } |
- } else if (radix == 16) { |
- if (*current == '0') { |
- // Allow "0x" prefix. |
- ++current; |
- if (current == end) return SignedZero(negative); |
- if (*current == 'x' || *current == 'X') { |
- ++current; |
- if (current == end) return JUNK_STRING_VALUE; |
- } else { |
- leading_zero = true; |
- } |
- } |
- } |
- |
- if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; |
- |
- // Skip leading zeros. |
- while (*current == '0') { |
- leading_zero = true; |
- ++current; |
- if (current == end) return SignedZero(negative); |
- } |
- |
- if (!leading_zero && !isDigit(*current, radix)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- if (IsPowerOf2(radix)) { |
- switch (radix) { |
- case 2: |
- return InternalStringToIntDouble<1>( |
- unicode_cache, current, end, negative, allow_trailing_junk); |
- case 4: |
- return InternalStringToIntDouble<2>( |
- unicode_cache, current, end, negative, allow_trailing_junk); |
- case 8: |
- return InternalStringToIntDouble<3>( |
- unicode_cache, current, end, negative, allow_trailing_junk); |
- |
- case 16: |
- return InternalStringToIntDouble<4>( |
- unicode_cache, current, end, negative, allow_trailing_junk); |
- |
- case 32: |
- return InternalStringToIntDouble<5>( |
- unicode_cache, current, end, negative, allow_trailing_junk); |
- default: |
- UNREACHABLE(); |
- } |
- } |
- |
- if (radix == 10) { |
- // Parsing with strtod. |
- const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. |
- // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero |
- // end. |
- const int kBufferSize = kMaxSignificantDigits + 2; |
- char buffer[kBufferSize]; |
- int buffer_pos = 0; |
- while (*current >= '0' && *current <= '9') { |
- if (buffer_pos <= kMaxSignificantDigits) { |
- // If the number has more than kMaxSignificantDigits it will be parsed |
- // as infinity. |
- ASSERT(buffer_pos < kBufferSize); |
- buffer[buffer_pos++] = static_cast<char>(*current); |
- } |
- ++current; |
- if (current == end) break; |
- } |
- |
- if (!allow_trailing_junk && |
- AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- ASSERT(buffer_pos < kBufferSize); |
- buffer[buffer_pos] = '\0'; |
- Vector<const char> buffer_vector(buffer, buffer_pos); |
- return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); |
- } |
- |
- // The following code causes accumulating rounding error for numbers greater |
- // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, |
- // 16, or 32, then mathInt may be an implementation-dependent approximation to |
- // the mathematical integer value" (15.1.2.2). |
- |
- int lim_0 = '0' + (radix < 10 ? radix : 10); |
- int lim_a = 'a' + (radix - 10); |
- int lim_A = 'A' + (radix - 10); |
- |
- // NOTE: The code for computing the value may seem a bit complex at |
- // first glance. It is structured to use 32-bit multiply-and-add |
- // loops as long as possible to avoid loosing precision. |
- |
- double v = 0.0; |
- bool done = false; |
- do { |
- // Parse the longest part of the string starting at index j |
- // possible while keeping the multiplier, and thus the part |
- // itself, within 32 bits. |
- unsigned int part = 0, multiplier = 1; |
- while (true) { |
- int d; |
- if (*current >= '0' && *current < lim_0) { |
- d = *current - '0'; |
- } else if (*current >= 'a' && *current < lim_a) { |
- d = *current - 'a' + 10; |
- } else if (*current >= 'A' && *current < lim_A) { |
- d = *current - 'A' + 10; |
- } else { |
- done = true; |
- break; |
- } |
- |
- // Update the value of the part as long as the multiplier fits |
- // in 32 bits. When we can't guarantee that the next iteration |
- // will not overflow the multiplier, we stop parsing the part |
- // by leaving the loop. |
- const unsigned int kMaximumMultiplier = 0xffffffffU / 36; |
- uint32_t m = multiplier * radix; |
- if (m > kMaximumMultiplier) break; |
- part = part * radix + d; |
- multiplier = m; |
- ASSERT(multiplier > part); |
- |
- ++current; |
- if (current == end) { |
- done = true; |
- break; |
- } |
- } |
- |
- // Update the value and skip the part in the string. |
- v = v * multiplier + part; |
- } while (!done); |
- |
- if (!allow_trailing_junk && |
- AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- return negative ? -v : v; |
-} |
- |
- |
-// Converts a string to a double value. Assumes the Iterator supports |
-// the following operations: |
-// 1. current == end (other ops are not allowed), current != end. |
-// 2. *current - gets the current character in the sequence. |
-// 3. ++current (advances the position). |
-template <class Iterator, class EndMark> |
-static double InternalStringToDouble(UnicodeCache* unicode_cache, |
- Iterator current, |
- EndMark end, |
- int flags, |
- double empty_string_val) { |
- // To make sure that iterator dereferencing is valid the following |
- // convention is used: |
- // 1. Each '++current' statement is followed by check for equality to 'end'. |
- // 2. If AdvanceToNonspace returned false then current == end. |
- // 3. If 'current' becomes be equal to 'end' the function returns or goes to |
- // 'parsing_done'. |
- // 4. 'current' is not dereferenced after the 'parsing_done' label. |
- // 5. Code before 'parsing_done' may rely on 'current != end'. |
- if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return empty_string_val; |
- } |
- |
- const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; |
- |
- // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". |
- const int kBufferSize = kMaxSignificantDigits + 10; |
- char buffer[kBufferSize]; // NOLINT: size is known at compile time. |
- int buffer_pos = 0; |
- |
- // Exponent will be adjusted if insignificant digits of the integer part |
- // or insignificant leading zeros of the fractional part are dropped. |
- int exponent = 0; |
- int significant_digits = 0; |
- int insignificant_digits = 0; |
- bool nonzero_digit_dropped = false; |
- bool fractional_part = false; |
- |
- bool negative = false; |
- |
- if (*current == '+') { |
- // Ignore leading sign. |
- ++current; |
- if (current == end) return JUNK_STRING_VALUE; |
- } else if (*current == '-') { |
- ++current; |
- if (current == end) return JUNK_STRING_VALUE; |
- negative = true; |
- } |
- |
- static const char kInfinitySymbol[] = "Infinity"; |
- if (*current == kInfinitySymbol[0]) { |
- if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- if (!allow_trailing_junk && |
- AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- ASSERT(buffer_pos == 0); |
- return negative ? -V8_INFINITY : V8_INFINITY; |
- } |
- |
- bool leading_zero = false; |
- if (*current == '0') { |
- ++current; |
- if (current == end) return SignedZero(negative); |
- |
- leading_zero = true; |
- |
- // It could be hexadecimal value. |
- if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
- ++current; |
- if (current == end || !isDigit(*current, 16)) { |
- return JUNK_STRING_VALUE; // "0x". |
- } |
- |
- return InternalStringToIntDouble<4>(unicode_cache, |
- current, |
- end, |
- negative, |
- allow_trailing_junk); |
- } |
- |
- // Ignore leading zeros in the integer part. |
- while (*current == '0') { |
- ++current; |
- if (current == end) return SignedZero(negative); |
- } |
- } |
- |
- bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; |
- |
- // Copy significant digits of the integer part (if any) to the buffer. |
- while (*current >= '0' && *current <= '9') { |
- if (significant_digits < kMaxSignificantDigits) { |
- ASSERT(buffer_pos < kBufferSize); |
- buffer[buffer_pos++] = static_cast<char>(*current); |
- significant_digits++; |
- // Will later check if it's an octal in the buffer. |
- } else { |
- insignificant_digits++; // Move the digit into the exponential part. |
- nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
- } |
- octal = octal && *current < '8'; |
- ++current; |
- if (current == end) goto parsing_done; |
- } |
- |
- if (significant_digits == 0) { |
- octal = false; |
- } |
- |
- if (*current == '.') { |
- if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE; |
- if (octal) goto parsing_done; |
- |
- ++current; |
- if (current == end) { |
- if (significant_digits == 0 && !leading_zero) { |
- return JUNK_STRING_VALUE; |
- } else { |
- goto parsing_done; |
- } |
- } |
- |
- if (significant_digits == 0) { |
- // octal = false; |
- // Integer part consists of 0 or is absent. Significant digits start after |
- // leading zeros (if any). |
- while (*current == '0') { |
- ++current; |
- if (current == end) return SignedZero(negative); |
- exponent--; // Move this 0 into the exponent. |
- } |
- } |
- |
- // We don't emit a '.', but adjust the exponent instead. |
- fractional_part = true; |
- |
- // There is a fractional part. |
- while (*current >= '0' && *current <= '9') { |
- if (significant_digits < kMaxSignificantDigits) { |
- ASSERT(buffer_pos < kBufferSize); |
- buffer[buffer_pos++] = static_cast<char>(*current); |
- significant_digits++; |
- exponent--; |
- } else { |
- // Ignore insignificant digits in the fractional part. |
- nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
- } |
- ++current; |
- if (current == end) goto parsing_done; |
- } |
- } |
- |
- if (!leading_zero && exponent == 0 && significant_digits == 0) { |
- // If leading_zeros is true then the string contains zeros. |
- // If exponent < 0 then string was [+-]\.0*... |
- // If significant_digits != 0 the string is not equal to 0. |
- // Otherwise there are no digits in the string. |
- return JUNK_STRING_VALUE; |
- } |
- |
- // Parse exponential part. |
- if (*current == 'e' || *current == 'E') { |
- if (octal) return JUNK_STRING_VALUE; |
- ++current; |
- if (current == end) { |
- if (allow_trailing_junk) { |
- goto parsing_done; |
- } else { |
- return JUNK_STRING_VALUE; |
- } |
- } |
- char sign = '+'; |
- if (*current == '+' || *current == '-') { |
- sign = static_cast<char>(*current); |
- ++current; |
- if (current == end) { |
- if (allow_trailing_junk) { |
- goto parsing_done; |
- } else { |
- return JUNK_STRING_VALUE; |
- } |
- } |
- } |
- |
- if (current == end || *current < '0' || *current > '9') { |
- if (allow_trailing_junk) { |
- goto parsing_done; |
- } else { |
- return JUNK_STRING_VALUE; |
- } |
- } |
- |
- const int max_exponent = INT_MAX / 2; |
- ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); |
- int num = 0; |
- do { |
- // Check overflow. |
- int digit = *current - '0'; |
- if (num >= max_exponent / 10 |
- && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { |
- num = max_exponent; |
- } else { |
- num = num * 10 + digit; |
- } |
- ++current; |
- } while (current != end && *current >= '0' && *current <= '9'); |
- |
- exponent += (sign == '-' ? -num : num); |
- } |
- |
- if (!allow_trailing_junk && |
- AdvanceToNonspace(unicode_cache, ¤t, end)) { |
- return JUNK_STRING_VALUE; |
- } |
- |
- parsing_done: |
- exponent += insignificant_digits; |
- |
- if (octal) { |
- return InternalStringToIntDouble<3>(unicode_cache, |
- buffer, |
- buffer + buffer_pos, |
- negative, |
- allow_trailing_junk); |
- } |
- |
- if (nonzero_digit_dropped) { |
- buffer[buffer_pos++] = '1'; |
- exponent--; |
- } |
- |
- ASSERT(buffer_pos < kBufferSize); |
- buffer[buffer_pos] = '\0'; |
- |
- double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
- return negative ? -converted : converted; |
-} |
- |
- |
-double StringToDouble(UnicodeCache* unicode_cache, |
- String* str, int flags, double empty_string_val) { |
- StringShape shape(str); |
- if (shape.IsSequentialAscii()) { |
- const char* begin = SeqAsciiString::cast(str)->GetChars(); |
- const char* end = begin + str->length(); |
- return InternalStringToDouble(unicode_cache, begin, end, flags, |
- empty_string_val); |
- } else if (shape.IsSequentialTwoByte()) { |
- const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); |
- const uc16* end = begin + str->length(); |
- return InternalStringToDouble(unicode_cache, begin, end, flags, |
- empty_string_val); |
- } else { |
- StringInputBuffer buffer(str); |
- return InternalStringToDouble(unicode_cache, |
- StringInputBufferIterator(&buffer), |
- StringInputBufferIterator::EndMarker(), |
- flags, |
- empty_string_val); |
- } |
-} |
- |
- |
-double StringToInt(UnicodeCache* unicode_cache, |
- String* str, |
- int radix) { |
- StringShape shape(str); |
- if (shape.IsSequentialAscii()) { |
- const char* begin = SeqAsciiString::cast(str)->GetChars(); |
- const char* end = begin + str->length(); |
- return InternalStringToInt(unicode_cache, begin, end, radix); |
- } else if (shape.IsSequentialTwoByte()) { |
- const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); |
- const uc16* end = begin + str->length(); |
- return InternalStringToInt(unicode_cache, begin, end, radix); |
- } else { |
- StringInputBuffer buffer(str); |
- return InternalStringToInt(unicode_cache, |
- StringInputBufferIterator(&buffer), |
- StringInputBufferIterator::EndMarker(), |
- radix); |
- } |
-} |
double StringToDouble(UnicodeCache* unicode_cache, |
@@ -750,7 +72,7 @@ const char* DoubleToCString(double v, Vector<char> buffer) { |
case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity"); |
case FP_ZERO: return "0"; |
default: { |
- StringBuilder builder(buffer.start(), buffer.length()); |
+ SimpleStringBuilder builder(buffer.start(), buffer.length()); |
int decimal_point; |
int sign; |
const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; |
@@ -791,7 +113,7 @@ const char* DoubleToCString(double v, Vector<char> buffer) { |
builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); |
int exponent = decimal_point - 1; |
if (exponent < 0) exponent = -exponent; |
- builder.AddFormatted("%d", exponent); |
+ builder.AddDecimalInteger(exponent); |
} |
return builder.Finalize(); |
} |
@@ -869,7 +191,7 @@ char* DoubleToFixedCString(double value, int f) { |
unsigned rep_length = |
zero_prefix_length + decimal_rep_length + zero_postfix_length; |
- StringBuilder rep_builder(rep_length + 1); |
+ SimpleStringBuilder rep_builder(rep_length + 1); |
rep_builder.AddPadding('0', zero_prefix_length); |
rep_builder.AddString(decimal_rep); |
rep_builder.AddPadding('0', zero_postfix_length); |
@@ -878,7 +200,7 @@ char* DoubleToFixedCString(double value, int f) { |
// Create the result string by appending a minus and putting in a |
// decimal point if needed. |
unsigned result_size = decimal_point + f + 2; |
- StringBuilder builder(result_size + 1); |
+ SimpleStringBuilder builder(result_size + 1); |
if (negative) builder.AddCharacter('-'); |
builder.AddSubstring(rep, decimal_point); |
if (f > 0) { |
@@ -904,7 +226,7 @@ static char* CreateExponentialRepresentation(char* decimal_rep, |
// letter 'e', a minus or a plus depending on the exponent, and a |
// three digit exponent. |
unsigned result_size = significant_digits + 7; |
- StringBuilder builder(result_size + 1); |
+ SimpleStringBuilder builder(result_size + 1); |
if (negative) builder.AddCharacter('-'); |
builder.AddCharacter(decimal_rep[0]); |
@@ -917,7 +239,7 @@ static char* CreateExponentialRepresentation(char* decimal_rep, |
builder.AddCharacter('e'); |
builder.AddCharacter(negative_exponent ? '-' : '+'); |
- builder.AddFormatted("%d", exponent); |
+ builder.AddDecimalInteger(exponent); |
return builder.Finalize(); |
} |
@@ -1009,7 +331,7 @@ char* DoubleToPrecisionCString(double value, int p) { |
unsigned result_size = (decimal_point <= 0) |
? -decimal_point + p + 3 |
: p + 2; |
- StringBuilder builder(result_size + 1); |
+ SimpleStringBuilder builder(result_size + 1); |
if (negative) builder.AddCharacter('-'); |
if (decimal_point <= 0) { |
builder.AddString("0."); |
@@ -1101,7 +423,7 @@ char* DoubleToRadixCString(double value, int radix) { |
// If the number has a decimal part, leave room for the period. |
if (decimal_pos > 0) result_size++; |
// Allocate result and fill in the parts. |
- StringBuilder builder(result_size + 1); |
+ SimpleStringBuilder builder(result_size + 1); |
builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
if (decimal_pos > 0) builder.AddCharacter('.'); |
builder.AddSubstring(decimal_buffer, decimal_pos); |