1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/double-conversion/double-conversion.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,892 @@ 1.4 +// Copyright 2010 the V8 project authors. All rights reserved. 1.5 +// Redistribution and use in source and binary forms, with or without 1.6 +// modification, are permitted provided that the following conditions are 1.7 +// met: 1.8 +// 1.9 +// * Redistributions of source code must retain the above copyright 1.10 +// notice, this list of conditions and the following disclaimer. 1.11 +// * Redistributions in binary form must reproduce the above 1.12 +// copyright notice, this list of conditions and the following 1.13 +// disclaimer in the documentation and/or other materials provided 1.14 +// with the distribution. 1.15 +// * Neither the name of Google Inc. nor the names of its 1.16 +// contributors may be used to endorse or promote products derived 1.17 +// from this software without specific prior written permission. 1.18 +// 1.19 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.20 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.21 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.22 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.23 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.24 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.25 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.26 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.27 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.28 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.29 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.30 + 1.31 +#include <limits.h> 1.32 +#include <math.h> 1.33 + 1.34 +#include "double-conversion.h" 1.35 + 1.36 +#include "bignum-dtoa.h" 1.37 +#include "fast-dtoa.h" 1.38 +#include "fixed-dtoa.h" 1.39 +#include "ieee.h" 1.40 +#include "strtod.h" 1.41 +#include "utils.h" 1.42 + 1.43 +namespace double_conversion { 1.44 + 1.45 +const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { 1.46 + int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; 1.47 + static DoubleToStringConverter converter(flags, 1.48 + "Infinity", 1.49 + "NaN", 1.50 + 'e', 1.51 + -6, 21, 1.52 + 6, 0); 1.53 + return converter; 1.54 +} 1.55 + 1.56 + 1.57 +bool DoubleToStringConverter::HandleSpecialValues( 1.58 + double value, 1.59 + StringBuilder* result_builder) const { 1.60 + Double double_inspect(value); 1.61 + if (double_inspect.IsInfinite()) { 1.62 + if (infinity_symbol_ == NULL) return false; 1.63 + if (value < 0) { 1.64 + result_builder->AddCharacter('-'); 1.65 + } 1.66 + result_builder->AddString(infinity_symbol_); 1.67 + return true; 1.68 + } 1.69 + if (double_inspect.IsNan()) { 1.70 + if (nan_symbol_ == NULL) return false; 1.71 + result_builder->AddString(nan_symbol_); 1.72 + return true; 1.73 + } 1.74 + return false; 1.75 +} 1.76 + 1.77 + 1.78 +void DoubleToStringConverter::CreateExponentialRepresentation( 1.79 + const char* decimal_digits, 1.80 + int length, 1.81 + int exponent, 1.82 + StringBuilder* result_builder) const { 1.83 + ASSERT(length != 0); 1.84 + result_builder->AddCharacter(decimal_digits[0]); 1.85 + if (length != 1) { 1.86 + result_builder->AddCharacter('.'); 1.87 + result_builder->AddSubstring(&decimal_digits[1], length-1); 1.88 + } 1.89 + result_builder->AddCharacter(exponent_character_); 1.90 + if (exponent < 0) { 1.91 + result_builder->AddCharacter('-'); 1.92 + exponent = -exponent; 1.93 + } else { 1.94 + if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) { 1.95 + result_builder->AddCharacter('+'); 1.96 + } 1.97 + } 1.98 + if (exponent == 0) { 1.99 + result_builder->AddCharacter('0'); 1.100 + return; 1.101 + } 1.102 + ASSERT(exponent < 1e4); 1.103 + const int kMaxExponentLength = 5; 1.104 + char buffer[kMaxExponentLength + 1]; 1.105 + buffer[kMaxExponentLength] = '\0'; 1.106 + int first_char_pos = kMaxExponentLength; 1.107 + while (exponent > 0) { 1.108 + buffer[--first_char_pos] = '0' + (exponent % 10); 1.109 + exponent /= 10; 1.110 + } 1.111 + result_builder->AddSubstring(&buffer[first_char_pos], 1.112 + kMaxExponentLength - first_char_pos); 1.113 +} 1.114 + 1.115 + 1.116 +void DoubleToStringConverter::CreateDecimalRepresentation( 1.117 + const char* decimal_digits, 1.118 + int length, 1.119 + int decimal_point, 1.120 + int digits_after_point, 1.121 + StringBuilder* result_builder) const { 1.122 + // Create a representation that is padded with zeros if needed. 1.123 + if (decimal_point <= 0) { 1.124 + // "0.00000decimal_rep". 1.125 + result_builder->AddCharacter('0'); 1.126 + if (digits_after_point > 0) { 1.127 + result_builder->AddCharacter('.'); 1.128 + result_builder->AddPadding('0', -decimal_point); 1.129 + ASSERT(length <= digits_after_point - (-decimal_point)); 1.130 + result_builder->AddSubstring(decimal_digits, length); 1.131 + int remaining_digits = digits_after_point - (-decimal_point) - length; 1.132 + result_builder->AddPadding('0', remaining_digits); 1.133 + } 1.134 + } else if (decimal_point >= length) { 1.135 + // "decimal_rep0000.00000" or "decimal_rep.0000" 1.136 + result_builder->AddSubstring(decimal_digits, length); 1.137 + result_builder->AddPadding('0', decimal_point - length); 1.138 + if (digits_after_point > 0) { 1.139 + result_builder->AddCharacter('.'); 1.140 + result_builder->AddPadding('0', digits_after_point); 1.141 + } 1.142 + } else { 1.143 + // "decima.l_rep000" 1.144 + ASSERT(digits_after_point > 0); 1.145 + result_builder->AddSubstring(decimal_digits, decimal_point); 1.146 + result_builder->AddCharacter('.'); 1.147 + ASSERT(length - decimal_point <= digits_after_point); 1.148 + result_builder->AddSubstring(&decimal_digits[decimal_point], 1.149 + length - decimal_point); 1.150 + int remaining_digits = digits_after_point - (length - decimal_point); 1.151 + result_builder->AddPadding('0', remaining_digits); 1.152 + } 1.153 + if (digits_after_point == 0) { 1.154 + if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { 1.155 + result_builder->AddCharacter('.'); 1.156 + } 1.157 + if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { 1.158 + result_builder->AddCharacter('0'); 1.159 + } 1.160 + } 1.161 +} 1.162 + 1.163 + 1.164 +bool DoubleToStringConverter::ToShortestIeeeNumber( 1.165 + double value, 1.166 + StringBuilder* result_builder, 1.167 + DoubleToStringConverter::DtoaMode mode) const { 1.168 + ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE); 1.169 + if (Double(value).IsSpecial()) { 1.170 + return HandleSpecialValues(value, result_builder); 1.171 + } 1.172 + 1.173 + int decimal_point; 1.174 + bool sign; 1.175 + const int kDecimalRepCapacity = kBase10MaximalLength + 1; 1.176 + char decimal_rep[kDecimalRepCapacity]; 1.177 + int decimal_rep_length; 1.178 + 1.179 + DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity, 1.180 + &sign, &decimal_rep_length, &decimal_point); 1.181 + 1.182 + bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; 1.183 + if (sign && (value != 0.0 || !unique_zero)) { 1.184 + result_builder->AddCharacter('-'); 1.185 + } 1.186 + 1.187 + int exponent = decimal_point - 1; 1.188 + if ((decimal_in_shortest_low_ <= exponent) && 1.189 + (exponent < decimal_in_shortest_high_)) { 1.190 + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, 1.191 + decimal_point, 1.192 + Max(0, decimal_rep_length - decimal_point), 1.193 + result_builder); 1.194 + } else { 1.195 + CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, 1.196 + result_builder); 1.197 + } 1.198 + return true; 1.199 +} 1.200 + 1.201 + 1.202 +bool DoubleToStringConverter::ToFixed(double value, 1.203 + int requested_digits, 1.204 + StringBuilder* result_builder) const { 1.205 + ASSERT(kMaxFixedDigitsBeforePoint == 60); 1.206 + const double kFirstNonFixed = 1e60; 1.207 + 1.208 + if (Double(value).IsSpecial()) { 1.209 + return HandleSpecialValues(value, result_builder); 1.210 + } 1.211 + 1.212 + if (requested_digits > kMaxFixedDigitsAfterPoint) return false; 1.213 + if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false; 1.214 + 1.215 + // Find a sufficiently precise decimal representation of n. 1.216 + int decimal_point; 1.217 + bool sign; 1.218 + // Add space for the '\0' byte. 1.219 + const int kDecimalRepCapacity = 1.220 + kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; 1.221 + char decimal_rep[kDecimalRepCapacity]; 1.222 + int decimal_rep_length; 1.223 + DoubleToAscii(value, FIXED, requested_digits, 1.224 + decimal_rep, kDecimalRepCapacity, 1.225 + &sign, &decimal_rep_length, &decimal_point); 1.226 + 1.227 + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); 1.228 + if (sign && (value != 0.0 || !unique_zero)) { 1.229 + result_builder->AddCharacter('-'); 1.230 + } 1.231 + 1.232 + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, 1.233 + requested_digits, result_builder); 1.234 + return true; 1.235 +} 1.236 + 1.237 + 1.238 +bool DoubleToStringConverter::ToExponential( 1.239 + double value, 1.240 + int requested_digits, 1.241 + StringBuilder* result_builder) const { 1.242 + if (Double(value).IsSpecial()) { 1.243 + return HandleSpecialValues(value, result_builder); 1.244 + } 1.245 + 1.246 + if (requested_digits < -1) return false; 1.247 + if (requested_digits > kMaxExponentialDigits) return false; 1.248 + 1.249 + int decimal_point; 1.250 + bool sign; 1.251 + // Add space for digit before the decimal point and the '\0' character. 1.252 + const int kDecimalRepCapacity = kMaxExponentialDigits + 2; 1.253 + ASSERT(kDecimalRepCapacity > kBase10MaximalLength); 1.254 + char decimal_rep[kDecimalRepCapacity]; 1.255 + int decimal_rep_length; 1.256 + 1.257 + if (requested_digits == -1) { 1.258 + DoubleToAscii(value, SHORTEST, 0, 1.259 + decimal_rep, kDecimalRepCapacity, 1.260 + &sign, &decimal_rep_length, &decimal_point); 1.261 + } else { 1.262 + DoubleToAscii(value, PRECISION, requested_digits + 1, 1.263 + decimal_rep, kDecimalRepCapacity, 1.264 + &sign, &decimal_rep_length, &decimal_point); 1.265 + ASSERT(decimal_rep_length <= requested_digits + 1); 1.266 + 1.267 + for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { 1.268 + decimal_rep[i] = '0'; 1.269 + } 1.270 + decimal_rep_length = requested_digits + 1; 1.271 + } 1.272 + 1.273 + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); 1.274 + if (sign && (value != 0.0 || !unique_zero)) { 1.275 + result_builder->AddCharacter('-'); 1.276 + } 1.277 + 1.278 + int exponent = decimal_point - 1; 1.279 + CreateExponentialRepresentation(decimal_rep, 1.280 + decimal_rep_length, 1.281 + exponent, 1.282 + result_builder); 1.283 + return true; 1.284 +} 1.285 + 1.286 + 1.287 +bool DoubleToStringConverter::ToPrecision(double value, 1.288 + int precision, 1.289 + bool* used_exponential_notation, 1.290 + StringBuilder* result_builder) const { 1.291 + *used_exponential_notation = false; 1.292 + if (Double(value).IsSpecial()) { 1.293 + return HandleSpecialValues(value, result_builder); 1.294 + } 1.295 + 1.296 + if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { 1.297 + return false; 1.298 + } 1.299 + 1.300 + // Find a sufficiently precise decimal representation of n. 1.301 + int decimal_point; 1.302 + bool sign; 1.303 + // Add one for the terminating null character. 1.304 + const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; 1.305 + char decimal_rep[kDecimalRepCapacity]; 1.306 + int decimal_rep_length; 1.307 + 1.308 + DoubleToAscii(value, PRECISION, precision, 1.309 + decimal_rep, kDecimalRepCapacity, 1.310 + &sign, &decimal_rep_length, &decimal_point); 1.311 + ASSERT(decimal_rep_length <= precision); 1.312 + 1.313 + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); 1.314 + if (sign && (value != 0.0 || !unique_zero)) { 1.315 + result_builder->AddCharacter('-'); 1.316 + } 1.317 + 1.318 + // The exponent if we print the number as x.xxeyyy. That is with the 1.319 + // decimal point after the first digit. 1.320 + int exponent = decimal_point - 1; 1.321 + 1.322 + int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; 1.323 + if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || 1.324 + (decimal_point - precision + extra_zero > 1.325 + max_trailing_padding_zeroes_in_precision_mode_)) { 1.326 + // Fill buffer to contain 'precision' digits. 1.327 + // Usually the buffer is already at the correct length, but 'DoubleToAscii' 1.328 + // is allowed to return less characters. 1.329 + for (int i = decimal_rep_length; i < precision; ++i) { 1.330 + decimal_rep[i] = '0'; 1.331 + } 1.332 + 1.333 + *used_exponential_notation = true; 1.334 + CreateExponentialRepresentation(decimal_rep, 1.335 + precision, 1.336 + exponent, 1.337 + result_builder); 1.338 + } else { 1.339 + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, 1.340 + Max(0, precision - decimal_point), 1.341 + result_builder); 1.342 + } 1.343 + return true; 1.344 +} 1.345 + 1.346 + 1.347 +static BignumDtoaMode DtoaToBignumDtoaMode( 1.348 + DoubleToStringConverter::DtoaMode dtoa_mode) { 1.349 + switch (dtoa_mode) { 1.350 + case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST; 1.351 + case DoubleToStringConverter::SHORTEST_SINGLE: 1.352 + return BIGNUM_DTOA_SHORTEST_SINGLE; 1.353 + case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED; 1.354 + case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION; 1.355 + default: 1.356 + UNREACHABLE(); 1.357 + return BIGNUM_DTOA_SHORTEST; // To silence compiler. 1.358 + } 1.359 +} 1.360 + 1.361 + 1.362 +void DoubleToStringConverter::DoubleToAscii(double v, 1.363 + DtoaMode mode, 1.364 + int requested_digits, 1.365 + char* buffer, 1.366 + int buffer_length, 1.367 + bool* sign, 1.368 + int* length, 1.369 + int* point) { 1.370 + Vector<char> vector(buffer, buffer_length); 1.371 + ASSERT(!Double(v).IsSpecial()); 1.372 + ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0); 1.373 + 1.374 + if (Double(v).Sign() < 0) { 1.375 + *sign = true; 1.376 + v = -v; 1.377 + } else { 1.378 + *sign = false; 1.379 + } 1.380 + 1.381 + if (mode == PRECISION && requested_digits == 0) { 1.382 + vector[0] = '\0'; 1.383 + *length = 0; 1.384 + return; 1.385 + } 1.386 + 1.387 + if (v == 0) { 1.388 + vector[0] = '0'; 1.389 + vector[1] = '\0'; 1.390 + *length = 1; 1.391 + *point = 1; 1.392 + return; 1.393 + } 1.394 + 1.395 + bool fast_worked; 1.396 + switch (mode) { 1.397 + case SHORTEST: 1.398 + fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); 1.399 + break; 1.400 + case SHORTEST_SINGLE: 1.401 + fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, 1.402 + vector, length, point); 1.403 + break; 1.404 + case FIXED: 1.405 + fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); 1.406 + break; 1.407 + case PRECISION: 1.408 + fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, 1.409 + vector, length, point); 1.410 + break; 1.411 + default: 1.412 + UNREACHABLE(); 1.413 + fast_worked = false; 1.414 + } 1.415 + if (fast_worked) return; 1.416 + 1.417 + // If the fast dtoa didn't succeed use the slower bignum version. 1.418 + BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); 1.419 + BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); 1.420 + vector[*length] = '\0'; 1.421 +} 1.422 + 1.423 + 1.424 +// Consumes the given substring from the iterator. 1.425 +// Returns false, if the substring does not match. 1.426 +static bool ConsumeSubString(const char** current, 1.427 + const char* end, 1.428 + const char* substring) { 1.429 + ASSERT(**current == *substring); 1.430 + for (substring++; *substring != '\0'; substring++) { 1.431 + ++*current; 1.432 + if (*current == end || **current != *substring) return false; 1.433 + } 1.434 + ++*current; 1.435 + return true; 1.436 +} 1.437 + 1.438 + 1.439 +// Maximum number of significant digits in decimal representation. 1.440 +// The longest possible double in decimal representation is 1.441 +// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 1.442 +// (768 digits). If we parse a number whose first digits are equal to a 1.443 +// mean of 2 adjacent doubles (that could have up to 769 digits) the result 1.444 +// must be rounded to the bigger one unless the tail consists of zeros, so 1.445 +// we don't need to preserve all the digits. 1.446 +const int kMaxSignificantDigits = 772; 1.447 + 1.448 + 1.449 +// Returns true if a nonspace found and false if the end has reached. 1.450 +static inline bool AdvanceToNonspace(const char** current, const char* end) { 1.451 + while (*current != end) { 1.452 + if (**current != ' ') return true; 1.453 + ++*current; 1.454 + } 1.455 + return false; 1.456 +} 1.457 + 1.458 + 1.459 +static bool isDigit(int x, int radix) { 1.460 + return (x >= '0' && x <= '9' && x < '0' + radix) 1.461 + || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) 1.462 + || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); 1.463 +} 1.464 + 1.465 + 1.466 +static double SignedZero(bool sign) { 1.467 + return sign ? -0.0 : 0.0; 1.468 +} 1.469 + 1.470 + 1.471 +// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. 1.472 +template <int radix_log_2> 1.473 +static double RadixStringToIeee(const char* current, 1.474 + const char* end, 1.475 + bool sign, 1.476 + bool allow_trailing_junk, 1.477 + double junk_string_value, 1.478 + bool read_as_double, 1.479 + const char** trailing_pointer) { 1.480 + ASSERT(current != end); 1.481 + 1.482 + const int kDoubleSize = Double::kSignificandSize; 1.483 + const int kSingleSize = Single::kSignificandSize; 1.484 + const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize; 1.485 + 1.486 + // Skip leading 0s. 1.487 + while (*current == '0') { 1.488 + ++current; 1.489 + if (current == end) { 1.490 + *trailing_pointer = end; 1.491 + return SignedZero(sign); 1.492 + } 1.493 + } 1.494 + 1.495 + int64_t number = 0; 1.496 + int exponent = 0; 1.497 + const int radix = (1 << radix_log_2); 1.498 + 1.499 + do { 1.500 + int digit; 1.501 + if (*current >= '0' && *current <= '9' && *current < '0' + radix) { 1.502 + digit = static_cast<char>(*current) - '0'; 1.503 + } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { 1.504 + digit = static_cast<char>(*current) - 'a' + 10; 1.505 + } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { 1.506 + digit = static_cast<char>(*current) - 'A' + 10; 1.507 + } else { 1.508 + if (allow_trailing_junk || !AdvanceToNonspace(¤t, end)) { 1.509 + break; 1.510 + } else { 1.511 + return junk_string_value; 1.512 + } 1.513 + } 1.514 + 1.515 + number = number * radix + digit; 1.516 + int overflow = static_cast<int>(number >> kSignificandSize); 1.517 + if (overflow != 0) { 1.518 + // Overflow occurred. Need to determine which direction to round the 1.519 + // result. 1.520 + int overflow_bits_count = 1; 1.521 + while (overflow > 1) { 1.522 + overflow_bits_count++; 1.523 + overflow >>= 1; 1.524 + } 1.525 + 1.526 + int dropped_bits_mask = ((1 << overflow_bits_count) - 1); 1.527 + int dropped_bits = static_cast<int>(number) & dropped_bits_mask; 1.528 + number >>= overflow_bits_count; 1.529 + exponent = overflow_bits_count; 1.530 + 1.531 + bool zero_tail = true; 1.532 + while (true) { 1.533 + ++current; 1.534 + if (current == end || !isDigit(*current, radix)) break; 1.535 + zero_tail = zero_tail && *current == '0'; 1.536 + exponent += radix_log_2; 1.537 + } 1.538 + 1.539 + if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { 1.540 + return junk_string_value; 1.541 + } 1.542 + 1.543 + int middle_value = (1 << (overflow_bits_count - 1)); 1.544 + if (dropped_bits > middle_value) { 1.545 + number++; // Rounding up. 1.546 + } else if (dropped_bits == middle_value) { 1.547 + // Rounding to even to consistency with decimals: half-way case rounds 1.548 + // up if significant part is odd and down otherwise. 1.549 + if ((number & 1) != 0 || !zero_tail) { 1.550 + number++; // Rounding up. 1.551 + } 1.552 + } 1.553 + 1.554 + // Rounding up may cause overflow. 1.555 + if ((number & ((int64_t)1 << kSignificandSize)) != 0) { 1.556 + exponent++; 1.557 + number >>= 1; 1.558 + } 1.559 + break; 1.560 + } 1.561 + ++current; 1.562 + } while (current != end); 1.563 + 1.564 + ASSERT(number < ((int64_t)1 << kSignificandSize)); 1.565 + ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); 1.566 + 1.567 + *trailing_pointer = current; 1.568 + 1.569 + if (exponent == 0) { 1.570 + if (sign) { 1.571 + if (number == 0) return -0.0; 1.572 + number = -number; 1.573 + } 1.574 + return static_cast<double>(number); 1.575 + } 1.576 + 1.577 + ASSERT(number != 0); 1.578 + return Double(DiyFp(number, exponent)).value(); 1.579 +} 1.580 + 1.581 + 1.582 +double StringToDoubleConverter::StringToIeee( 1.583 + const char* input, 1.584 + int length, 1.585 + int* processed_characters_count, 1.586 + bool read_as_double) const { 1.587 + const char* current = input; 1.588 + const char* end = input + length; 1.589 + 1.590 + *processed_characters_count = 0; 1.591 + 1.592 + const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; 1.593 + const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; 1.594 + const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; 1.595 + const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; 1.596 + 1.597 + // To make sure that iterator dereferencing is valid the following 1.598 + // convention is used: 1.599 + // 1. Each '++current' statement is followed by check for equality to 'end'. 1.600 + // 2. If AdvanceToNonspace returned false then current == end. 1.601 + // 3. If 'current' becomes equal to 'end' the function returns or goes to 1.602 + // 'parsing_done'. 1.603 + // 4. 'current' is not dereferenced after the 'parsing_done' label. 1.604 + // 5. Code before 'parsing_done' may rely on 'current != end'. 1.605 + if (current == end) return empty_string_value_; 1.606 + 1.607 + if (allow_leading_spaces || allow_trailing_spaces) { 1.608 + if (!AdvanceToNonspace(¤t, end)) { 1.609 + *processed_characters_count = current - input; 1.610 + return empty_string_value_; 1.611 + } 1.612 + if (!allow_leading_spaces && (input != current)) { 1.613 + // No leading spaces allowed, but AdvanceToNonspace moved forward. 1.614 + return junk_string_value_; 1.615 + } 1.616 + } 1.617 + 1.618 + // The longest form of simplified number is: "-<significant digits>.1eXXX\0". 1.619 + const int kBufferSize = kMaxSignificantDigits + 10; 1.620 + char buffer[kBufferSize]; // NOLINT: size is known at compile time. 1.621 + int buffer_pos = 0; 1.622 + 1.623 + // Exponent will be adjusted if insignificant digits of the integer part 1.624 + // or insignificant leading zeros of the fractional part are dropped. 1.625 + int exponent = 0; 1.626 + int significant_digits = 0; 1.627 + int insignificant_digits = 0; 1.628 + bool nonzero_digit_dropped = false; 1.629 + 1.630 + bool sign = false; 1.631 + 1.632 + if (*current == '+' || *current == '-') { 1.633 + sign = (*current == '-'); 1.634 + ++current; 1.635 + const char* next_non_space = current; 1.636 + // Skip following spaces (if allowed). 1.637 + if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; 1.638 + if (!allow_spaces_after_sign && (current != next_non_space)) { 1.639 + return junk_string_value_; 1.640 + } 1.641 + current = next_non_space; 1.642 + } 1.643 + 1.644 + if (infinity_symbol_ != NULL) { 1.645 + if (*current == infinity_symbol_[0]) { 1.646 + if (!ConsumeSubString(¤t, end, infinity_symbol_)) { 1.647 + return junk_string_value_; 1.648 + } 1.649 + 1.650 + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { 1.651 + return junk_string_value_; 1.652 + } 1.653 + if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { 1.654 + return junk_string_value_; 1.655 + } 1.656 + 1.657 + ASSERT(buffer_pos == 0); 1.658 + *processed_characters_count = current - input; 1.659 + return sign ? -Double::Infinity() : Double::Infinity(); 1.660 + } 1.661 + } 1.662 + 1.663 + if (nan_symbol_ != NULL) { 1.664 + if (*current == nan_symbol_[0]) { 1.665 + if (!ConsumeSubString(¤t, end, nan_symbol_)) { 1.666 + return junk_string_value_; 1.667 + } 1.668 + 1.669 + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { 1.670 + return junk_string_value_; 1.671 + } 1.672 + if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { 1.673 + return junk_string_value_; 1.674 + } 1.675 + 1.676 + ASSERT(buffer_pos == 0); 1.677 + *processed_characters_count = current - input; 1.678 + return sign ? -Double::NaN() : Double::NaN(); 1.679 + } 1.680 + } 1.681 + 1.682 + bool leading_zero = false; 1.683 + if (*current == '0') { 1.684 + ++current; 1.685 + if (current == end) { 1.686 + *processed_characters_count = current - input; 1.687 + return SignedZero(sign); 1.688 + } 1.689 + 1.690 + leading_zero = true; 1.691 + 1.692 + // It could be hexadecimal value. 1.693 + if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { 1.694 + ++current; 1.695 + if (current == end || !isDigit(*current, 16)) { 1.696 + return junk_string_value_; // "0x". 1.697 + } 1.698 + 1.699 + const char* tail_pointer = NULL; 1.700 + double result = RadixStringToIeee<4>(current, 1.701 + end, 1.702 + sign, 1.703 + allow_trailing_junk, 1.704 + junk_string_value_, 1.705 + read_as_double, 1.706 + &tail_pointer); 1.707 + if (tail_pointer != NULL) { 1.708 + if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end); 1.709 + *processed_characters_count = tail_pointer - input; 1.710 + } 1.711 + return result; 1.712 + } 1.713 + 1.714 + // Ignore leading zeros in the integer part. 1.715 + while (*current == '0') { 1.716 + ++current; 1.717 + if (current == end) { 1.718 + *processed_characters_count = current - input; 1.719 + return SignedZero(sign); 1.720 + } 1.721 + } 1.722 + } 1.723 + 1.724 + bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0; 1.725 + 1.726 + // Copy significant digits of the integer part (if any) to the buffer. 1.727 + while (*current >= '0' && *current <= '9') { 1.728 + if (significant_digits < kMaxSignificantDigits) { 1.729 + ASSERT(buffer_pos < kBufferSize); 1.730 + buffer[buffer_pos++] = static_cast<char>(*current); 1.731 + significant_digits++; 1.732 + // Will later check if it's an octal in the buffer. 1.733 + } else { 1.734 + insignificant_digits++; // Move the digit into the exponential part. 1.735 + nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 1.736 + } 1.737 + octal = octal && *current < '8'; 1.738 + ++current; 1.739 + if (current == end) goto parsing_done; 1.740 + } 1.741 + 1.742 + if (significant_digits == 0) { 1.743 + octal = false; 1.744 + } 1.745 + 1.746 + if (*current == '.') { 1.747 + if (octal && !allow_trailing_junk) return junk_string_value_; 1.748 + if (octal) goto parsing_done; 1.749 + 1.750 + ++current; 1.751 + if (current == end) { 1.752 + if (significant_digits == 0 && !leading_zero) { 1.753 + return junk_string_value_; 1.754 + } else { 1.755 + goto parsing_done; 1.756 + } 1.757 + } 1.758 + 1.759 + if (significant_digits == 0) { 1.760 + // octal = false; 1.761 + // Integer part consists of 0 or is absent. Significant digits start after 1.762 + // leading zeros (if any). 1.763 + while (*current == '0') { 1.764 + ++current; 1.765 + if (current == end) { 1.766 + *processed_characters_count = current - input; 1.767 + return SignedZero(sign); 1.768 + } 1.769 + exponent--; // Move this 0 into the exponent. 1.770 + } 1.771 + } 1.772 + 1.773 + // There is a fractional part. 1.774 + // We don't emit a '.', but adjust the exponent instead. 1.775 + while (*current >= '0' && *current <= '9') { 1.776 + if (significant_digits < kMaxSignificantDigits) { 1.777 + ASSERT(buffer_pos < kBufferSize); 1.778 + buffer[buffer_pos++] = static_cast<char>(*current); 1.779 + significant_digits++; 1.780 + exponent--; 1.781 + } else { 1.782 + // Ignore insignificant digits in the fractional part. 1.783 + nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 1.784 + } 1.785 + ++current; 1.786 + if (current == end) goto parsing_done; 1.787 + } 1.788 + } 1.789 + 1.790 + if (!leading_zero && exponent == 0 && significant_digits == 0) { 1.791 + // If leading_zeros is true then the string contains zeros. 1.792 + // If exponent < 0 then string was [+-]\.0*... 1.793 + // If significant_digits != 0 the string is not equal to 0. 1.794 + // Otherwise there are no digits in the string. 1.795 + return junk_string_value_; 1.796 + } 1.797 + 1.798 + // Parse exponential part. 1.799 + if (*current == 'e' || *current == 'E') { 1.800 + if (octal && !allow_trailing_junk) return junk_string_value_; 1.801 + if (octal) goto parsing_done; 1.802 + ++current; 1.803 + if (current == end) { 1.804 + if (allow_trailing_junk) { 1.805 + goto parsing_done; 1.806 + } else { 1.807 + return junk_string_value_; 1.808 + } 1.809 + } 1.810 + char sign = '+'; 1.811 + if (*current == '+' || *current == '-') { 1.812 + sign = static_cast<char>(*current); 1.813 + ++current; 1.814 + if (current == end) { 1.815 + if (allow_trailing_junk) { 1.816 + goto parsing_done; 1.817 + } else { 1.818 + return junk_string_value_; 1.819 + } 1.820 + } 1.821 + } 1.822 + 1.823 + if (current == end || *current < '0' || *current > '9') { 1.824 + if (allow_trailing_junk) { 1.825 + goto parsing_done; 1.826 + } else { 1.827 + return junk_string_value_; 1.828 + } 1.829 + } 1.830 + 1.831 + const int max_exponent = INT_MAX / 2; 1.832 + ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); 1.833 + int num = 0; 1.834 + do { 1.835 + // Check overflow. 1.836 + int digit = *current - '0'; 1.837 + if (num >= max_exponent / 10 1.838 + && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { 1.839 + num = max_exponent; 1.840 + } else { 1.841 + num = num * 10 + digit; 1.842 + } 1.843 + ++current; 1.844 + } while (current != end && *current >= '0' && *current <= '9'); 1.845 + 1.846 + exponent += (sign == '-' ? -num : num); 1.847 + } 1.848 + 1.849 + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { 1.850 + return junk_string_value_; 1.851 + } 1.852 + if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { 1.853 + return junk_string_value_; 1.854 + } 1.855 + if (allow_trailing_spaces) { 1.856 + AdvanceToNonspace(¤t, end); 1.857 + } 1.858 + 1.859 + parsing_done: 1.860 + exponent += insignificant_digits; 1.861 + 1.862 + if (octal) { 1.863 + double result; 1.864 + const char* tail_pointer = NULL; 1.865 + result = RadixStringToIeee<3>(buffer, 1.866 + buffer + buffer_pos, 1.867 + sign, 1.868 + allow_trailing_junk, 1.869 + junk_string_value_, 1.870 + read_as_double, 1.871 + &tail_pointer); 1.872 + ASSERT(tail_pointer != NULL); 1.873 + *processed_characters_count = current - input; 1.874 + return result; 1.875 + } 1.876 + 1.877 + if (nonzero_digit_dropped) { 1.878 + buffer[buffer_pos++] = '1'; 1.879 + exponent--; 1.880 + } 1.881 + 1.882 + ASSERT(buffer_pos < kBufferSize); 1.883 + buffer[buffer_pos] = '\0'; 1.884 + 1.885 + double converted; 1.886 + if (read_as_double) { 1.887 + converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); 1.888 + } else { 1.889 + converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent); 1.890 + } 1.891 + *processed_characters_count = current - input; 1.892 + return sign? -converted: converted; 1.893 +} 1.894 + 1.895 +} // namespace double_conversion