Index: third_party/WebKit/Source/wtf/dtoa/double-conversion.cc |
diff --git a/third_party/WebKit/Source/wtf/dtoa/double-conversion.cc b/third_party/WebKit/Source/wtf/dtoa/double-conversion.cc |
deleted file mode 100644 |
index 96fbdce3d047b96d48f76c26c0eddc365cd3f83d..0000000000000000000000000000000000000000 |
--- a/third_party/WebKit/Source/wtf/dtoa/double-conversion.cc |
+++ /dev/null |
@@ -1,603 +0,0 @@ |
-// Copyright 2010 the V8 project authors. All rights reserved. |
-// Redistribution and use in source and binary forms, with or without |
-// modification, are permitted provided that the following conditions are |
-// met: |
-// |
-// * Redistributions of source code must retain the above copyright |
-// notice, this list of conditions and the following disclaimer. |
-// * Redistributions in binary form must reproduce the above |
-// copyright notice, this list of conditions and the following |
-// disclaimer in the documentation and/or other materials provided |
-// with the distribution. |
-// * Neither the name of Google Inc. nor the names of its |
-// contributors may be used to endorse or promote products derived |
-// from this software without specific prior written permission. |
-// |
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- |
-#include "double-conversion.h" |
- |
-#include "bignum-dtoa.h" |
-#include "double.h" |
-#include "fast-dtoa.h" |
-#include "fixed-dtoa.h" |
-#include "strtod.h" |
-#include "utils.h" |
-#include <limits.h> |
-#include <math.h> |
- |
-namespace WTF { |
- |
-namespace double_conversion { |
- |
- const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { |
- int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; |
- static DoubleToStringConverter converter(flags, |
- "Infinity", |
- "NaN", |
- 'e', |
- -6, 21, |
- 6, 0); |
- return converter; |
- } |
- |
- |
- bool DoubleToStringConverter::HandleSpecialValues( |
- double value, |
- StringBuilder* result_builder) const { |
- Double double_inspect(value); |
- if (double_inspect.IsInfinite()) { |
- if (infinity_symbol_ == NULL) return false; |
- if (value < 0) { |
- result_builder->AddCharacter('-'); |
- } |
- result_builder->AddString(infinity_symbol_); |
- return true; |
- } |
- if (double_inspect.IsNan()) { |
- if (nan_symbol_ == NULL) return false; |
- result_builder->AddString(nan_symbol_); |
- return true; |
- } |
- return false; |
- } |
- |
- |
- void DoubleToStringConverter::CreateExponentialRepresentation( |
- const char* decimal_digits, |
- int length, |
- int exponent, |
- StringBuilder* result_builder) const { |
- ASSERT(length != 0); |
- result_builder->AddCharacter(decimal_digits[0]); |
- if (length != 1) { |
- result_builder->AddCharacter('.'); |
- result_builder->AddSubstring(&decimal_digits[1], length-1); |
- } |
- result_builder->AddCharacter(exponent_character_); |
- if (exponent < 0) { |
- result_builder->AddCharacter('-'); |
- exponent = -exponent; |
- } else { |
- if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) { |
- result_builder->AddCharacter('+'); |
- } |
- } |
- if (exponent == 0) { |
- result_builder->AddCharacter('0'); |
- return; |
- } |
- ASSERT(exponent < 1e4); |
- const int kMaxExponentLength = 5; |
- char buffer[kMaxExponentLength + 1]; |
- int first_char_pos = kMaxExponentLength; |
- buffer[first_char_pos] = '\0'; |
- while (exponent > 0) { |
- buffer[--first_char_pos] = '0' + (exponent % 10); |
- exponent /= 10; |
- } |
- result_builder->AddSubstring(&buffer[first_char_pos], |
- kMaxExponentLength - first_char_pos); |
- } |
- |
- |
- void DoubleToStringConverter::CreateDecimalRepresentation( |
- const char* decimal_digits, |
- int length, |
- int decimal_point, |
- int digits_after_point, |
- StringBuilder* result_builder) const { |
- // Create a representation that is padded with zeros if needed. |
- if (decimal_point <= 0) { |
- // "0.00000decimal_rep". |
- result_builder->AddCharacter('0'); |
- if (digits_after_point > 0) { |
- result_builder->AddCharacter('.'); |
- result_builder->AddPadding('0', -decimal_point); |
- ASSERT(length <= digits_after_point - (-decimal_point)); |
- result_builder->AddSubstring(decimal_digits, length); |
- int remaining_digits = digits_after_point - (-decimal_point) - length; |
- result_builder->AddPadding('0', remaining_digits); |
- } |
- } else if (decimal_point >= length) { |
- // "decimal_rep0000.00000" or "decimal_rep.0000" |
- result_builder->AddSubstring(decimal_digits, length); |
- result_builder->AddPadding('0', decimal_point - length); |
- if (digits_after_point > 0) { |
- result_builder->AddCharacter('.'); |
- result_builder->AddPadding('0', digits_after_point); |
- } |
- } else { |
- // "decima.l_rep000" |
- ASSERT(digits_after_point > 0); |
- result_builder->AddSubstring(decimal_digits, decimal_point); |
- result_builder->AddCharacter('.'); |
- ASSERT(length - decimal_point <= digits_after_point); |
- result_builder->AddSubstring(&decimal_digits[decimal_point], |
- length - decimal_point); |
- int remaining_digits = digits_after_point - (length - decimal_point); |
- result_builder->AddPadding('0', remaining_digits); |
- } |
- if (digits_after_point == 0) { |
- if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { |
- result_builder->AddCharacter('.'); |
- } |
- if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { |
- result_builder->AddCharacter('0'); |
- } |
- } |
- } |
- |
- |
- bool DoubleToStringConverter::ToShortest(double value, |
- StringBuilder* result_builder) const { |
- if (Double(value).IsSpecial()) { |
- return HandleSpecialValues(value, result_builder); |
- } |
- |
- int decimal_point; |
- bool sign; |
- const int kDecimalRepCapacity = kBase10MaximalLength + 1; |
- char decimal_rep[kDecimalRepCapacity]; |
- int decimal_rep_length; |
- |
- DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity, |
- &sign, &decimal_rep_length, &decimal_point); |
- |
- bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; |
- if (sign && (value != 0.0 || !unique_zero)) { |
- result_builder->AddCharacter('-'); |
- } |
- |
- int exponent = decimal_point - 1; |
- if ((decimal_in_shortest_low_ <= exponent) && |
- (exponent < decimal_in_shortest_high_)) { |
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, |
- decimal_point, |
- Max(0, decimal_rep_length - decimal_point), |
- result_builder); |
- } else { |
- CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, |
- result_builder); |
- } |
- return true; |
- } |
- |
- |
- bool DoubleToStringConverter::ToFixed(double value, |
- int requested_digits, |
- StringBuilder* result_builder) const { |
- ASSERT(kMaxFixedDigitsBeforePoint == 60); |
- const double kFirstNonFixed = 1e60; |
- |
- if (Double(value).IsSpecial()) { |
- return HandleSpecialValues(value, result_builder); |
- } |
- |
- if (requested_digits > kMaxFixedDigitsAfterPoint) return false; |
- if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false; |
- |
- // Find a sufficiently precise decimal representation of n. |
- int decimal_point; |
- bool sign; |
- // Add space for the '\0' byte. |
- const int kDecimalRepCapacity = |
- kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; |
- char decimal_rep[kDecimalRepCapacity]; |
- int decimal_rep_length; |
- DoubleToAscii(value, FIXED, requested_digits, |
- decimal_rep, kDecimalRepCapacity, |
- &sign, &decimal_rep_length, &decimal_point); |
- |
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); |
- if (sign && (value != 0.0 || !unique_zero)) { |
- result_builder->AddCharacter('-'); |
- } |
- |
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, |
- requested_digits, result_builder); |
- return true; |
- } |
- |
- |
- bool DoubleToStringConverter::ToExponential( |
- double value, |
- int requested_digits, |
- StringBuilder* result_builder) const { |
- if (Double(value).IsSpecial()) { |
- return HandleSpecialValues(value, result_builder); |
- } |
- |
- if (requested_digits < -1) return false; |
- if (requested_digits > kMaxExponentialDigits) return false; |
- |
- int decimal_point; |
- bool sign; |
- // Add space for digit before the decimal point and the '\0' character. |
- const int kDecimalRepCapacity = kMaxExponentialDigits + 2; |
- ASSERT(kDecimalRepCapacity > kBase10MaximalLength); |
- char decimal_rep[kDecimalRepCapacity]; |
- int decimal_rep_length; |
- |
- if (requested_digits == -1) { |
- DoubleToAscii(value, SHORTEST, 0, |
- decimal_rep, kDecimalRepCapacity, |
- &sign, &decimal_rep_length, &decimal_point); |
- } else { |
- DoubleToAscii(value, PRECISION, requested_digits + 1, |
- decimal_rep, kDecimalRepCapacity, |
- &sign, &decimal_rep_length, &decimal_point); |
- ASSERT(decimal_rep_length <= requested_digits + 1); |
- |
- for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { |
- decimal_rep[i] = '0'; |
- } |
- decimal_rep_length = requested_digits + 1; |
- } |
- |
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); |
- if (sign && (value != 0.0 || !unique_zero)) { |
- result_builder->AddCharacter('-'); |
- } |
- |
- int exponent = decimal_point - 1; |
- CreateExponentialRepresentation(decimal_rep, |
- decimal_rep_length, |
- exponent, |
- result_builder); |
- return true; |
- } |
- |
- |
- bool DoubleToStringConverter::ToPrecision(double value, |
- int precision, |
- StringBuilder* result_builder) const { |
- if (Double(value).IsSpecial()) { |
- return HandleSpecialValues(value, result_builder); |
- } |
- |
- if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { |
- return false; |
- } |
- |
- // Find a sufficiently precise decimal representation of n. |
- int decimal_point; |
- bool sign; |
- // Add one for the terminating null character. |
- const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; |
- char decimal_rep[kDecimalRepCapacity]; |
- int decimal_rep_length; |
- |
- DoubleToAscii(value, PRECISION, precision, |
- decimal_rep, kDecimalRepCapacity, |
- &sign, &decimal_rep_length, &decimal_point); |
- ASSERT(decimal_rep_length <= precision); |
- |
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); |
- if (sign && (value != 0.0 || !unique_zero)) { |
- result_builder->AddCharacter('-'); |
- } |
- |
- // The exponent if we print the number as x.xxeyyy. That is with the |
- // decimal point after the first digit. |
- int exponent = decimal_point - 1; |
- |
- int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; |
- if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || |
- (decimal_point - precision + extra_zero > |
- max_trailing_padding_zeroes_in_precision_mode_)) { |
- // Fill buffer to contain 'precision' digits. |
- // Usually the buffer is already at the correct length, but 'DoubleToAscii' |
- // is allowed to return less characters. |
- for (int i = decimal_rep_length; i < precision; ++i) { |
- decimal_rep[i] = '0'; |
- } |
- |
- CreateExponentialRepresentation(decimal_rep, |
- precision, |
- exponent, |
- result_builder); |
- } else { |
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, |
- Max(0, precision - decimal_point), |
- result_builder); |
- } |
- return true; |
- } |
- |
- |
- static BignumDtoaMode DtoaToBignumDtoaMode( |
- DoubleToStringConverter::DtoaMode dtoa_mode) { |
- switch (dtoa_mode) { |
- case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST; |
- case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED; |
- case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION; |
- default: |
- UNREACHABLE(); |
- return BIGNUM_DTOA_SHORTEST; // To silence compiler. |
- } |
- } |
- |
- |
- void DoubleToStringConverter::DoubleToAscii(double v, |
- DtoaMode mode, |
- int requested_digits, |
- char* buffer, |
- int buffer_length, |
- bool* sign, |
- int* length, |
- int* point) { |
- Vector<char> vector(buffer, buffer_length); |
- ASSERT(!Double(v).IsSpecial()); |
- ASSERT(mode == SHORTEST || requested_digits >= 0); |
- |
- if (Double(v).Sign() < 0) { |
- *sign = true; |
- v = -v; |
- } else { |
- *sign = false; |
- } |
- |
- if (mode == PRECISION && requested_digits == 0) { |
- vector[0] = '\0'; |
- *length = 0; |
- return; |
- } |
- |
- if (v == 0) { |
- vector[0] = '0'; |
- vector[1] = '\0'; |
- *length = 1; |
- *point = 1; |
- return; |
- } |
- |
- bool fast_worked; |
- switch (mode) { |
- case SHORTEST: |
- fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); |
- break; |
- case FIXED: |
- fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); |
- break; |
- case PRECISION: |
- fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, |
- vector, length, point); |
- break; |
- default: |
- UNREACHABLE(); |
- fast_worked = false; |
- } |
- if (fast_worked) return; |
- |
- // If the fast dtoa didn't succeed use the slower bignum version. |
- BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); |
- BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); |
- vector[*length] = '\0'; |
- } |
- |
- |
- // 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 double SignedZero(bool sign) { |
- return sign ? -0.0 : 0.0; |
- } |
- |
- |
- double StringToDoubleConverter::StringToDouble( |
- const char* input, |
- size_t length, |
- size_t* processed_characters_count) { |
- const char* current = input; |
- const char* end = input + length; |
- |
- *processed_characters_count = 0; |
- |
- // 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'. |
- // 3. If 'current' becomes 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 (current == end) return 0.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 sign = false; |
- |
- if (*current == '+' || *current == '-') { |
- sign = (*current == '-'); |
- ++current; |
- if (current == end) return 0.0; |
- } |
- |
- bool leading_zero = false; |
- if (*current == '0') { |
- ++current; |
- if (current == end) { |
- *processed_characters_count = current - input; |
- return SignedZero(sign); |
- } |
- |
- leading_zero = true; |
- |
- // Ignore leading zeros in the integer part. |
- while (*current == '0') { |
- ++current; |
- if (current == end) { |
- *processed_characters_count = current - input; |
- return SignedZero(sign); |
- } |
- } |
- } |
- |
- // 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++; |
- } else { |
- insignificant_digits++; // Move the digit into the exponential part. |
- nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
- } |
- ++current; |
- if (current == end) goto parsing_done; |
- } |
- |
- if (*current == '.') { |
- ++current; |
- if (current == end) { |
- if (significant_digits == 0 && !leading_zero) { |
- return 0.0; |
- } else { |
- goto parsing_done; |
- } |
- } |
- |
- if (significant_digits == 0) { |
- // Integer part consists of 0 or is absent. Significant digits start after |
- // leading zeros (if any). |
- while (*current == '0') { |
- ++current; |
- if (current == end) { |
- *processed_characters_count = current - input; |
- return SignedZero(sign); |
- } |
- exponent--; // Move this 0 into the exponent. |
- } |
- } |
- |
- // 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 0.0; |
- } |
- |
- // Parse exponential part. |
- if (*current == 'e' || *current == 'E') { |
- ++current; |
- if (current == end) { |
- --current; |
- goto parsing_done; |
- } |
- char sign = 0; |
- if (*current == '+' || *current == '-') { |
- sign = static_cast<char>(*current); |
- ++current; |
- if (current == end) { |
- current -= 2; |
- goto parsing_done; |
- } |
- } |
- |
- if (*current < '0' || *current > '9') { |
- if (sign) |
- --current; |
- --current; |
- goto parsing_done; |
- } |
- |
- 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); |
- } |
- |
- parsing_done: |
- exponent += insignificant_digits; |
- |
- 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); |
- *processed_characters_count = current - input; |
- return sign? -converted: converted; |
- } |
- |
-} // namespace double_conversion |
- |
-} // namespace WTF |