44 static const int kMaxExactDoubleIntegerDecimalDigits = 15;
46 static const int kMaxUint64DecimalDigits = 19;
54 static const int kMaxDecimalPower = 309;
55 static const int kMinDecimalPower = -324;
61 static const double exact_powers_of_ten[] = {
80 1000000000000000000.0,
81 10000000000000000000.0,
82 100000000000000000000.0,
83 1000000000000000000000.0,
85 10000000000000000000000.0
87 static const int kExactPowersOfTenSize =
ARRAY_SIZE(exact_powers_of_ten);
92 static const int kMaxSignificantDecimalDigits = 780;
94 static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
95 for (
int i = 0; i < buffer.length(); i++) {
96 if (buffer[i] !=
'0') {
97 return buffer.
SubVector(i, buffer.length());
100 return Vector<const char>(buffer.start(), 0);
104 static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
105 for (
int i = buffer.length() - 1; i >= 0; --i) {
106 if (buffer[i] !=
'0') {
110 return Vector<const char>(buffer.start(), 0);
114 static void TrimToMaxSignificantDigits(Vector<const char> buffer,
116 char* significant_buffer,
117 int* significant_exponent) {
118 for (
int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
119 significant_buffer[i] = buffer[i];
123 ASSERT(buffer[buffer.length() - 1] !=
'0');
126 significant_buffer[kMaxSignificantDecimalDigits - 1] =
'1';
127 *significant_exponent =
128 exponent + (buffer.length() - kMaxSignificantDecimalDigits);
137 static uint64_t ReadUint64(Vector<const char> buffer,
138 int* number_of_read_digits) {
141 while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
142 int digit = buffer[i++] -
'0';
143 ASSERT(0 <= digit && digit <= 9);
144 result = 10 * result + digit;
146 *number_of_read_digits = i;
155 static void ReadDiyFp(Vector<const char> buffer,
157 int* remaining_decimals) {
159 uint64_t significand = ReadUint64(buffer, &read_digits);
160 if (buffer.length() == read_digits) {
161 *result = DiyFp(significand, 0);
162 *remaining_decimals = 0;
165 if (buffer[read_digits] >=
'5') {
170 *result = DiyFp(significand, exponent);
171 *remaining_decimals = buffer.length() - read_digits;
176 static bool DoubleStrtod(Vector<const char> trimmed,
179 #if (V8_TARGET_ARCH_IA32 || defined(USE_SIMULATOR)) && !defined(_MSC_VER)
189 if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
197 if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
199 *result =
static_cast<double>(ReadUint64(trimmed, &read_digits));
200 ASSERT(read_digits == trimmed.length());
201 *result /= exact_powers_of_ten[-exponent];
204 if (0 <= exponent && exponent < kExactPowersOfTenSize) {
206 *result =
static_cast<double>(ReadUint64(trimmed, &read_digits));
207 ASSERT(read_digits == trimmed.length());
208 *result *= exact_powers_of_ten[exponent];
211 int remaining_digits =
212 kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
213 if ((0 <= exponent) &&
214 (exponent - remaining_digits < kExactPowersOfTenSize)) {
218 *result =
static_cast<double>(ReadUint64(trimmed, &read_digits));
219 ASSERT(read_digits == trimmed.length());
220 *result *= exact_powers_of_ten[remaining_digits];
221 *result *= exact_powers_of_ten[exponent - remaining_digits];
231 static DiyFp AdjustmentPowerOfTen(
int exponent) {
255 static bool DiyFpStrtod(Vector<const char> buffer,
259 int remaining_decimals;
260 ReadDiyFp(buffer, &input, &remaining_decimals);
266 const int kDenominatorLog = 3;
267 const int kDenominator = 1 << kDenominatorLog;
269 exponent += remaining_decimals;
270 int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
272 int old_e = input.e();
274 error <<= old_e - input.e();
282 int cached_decimal_exponent;
285 &cached_decimal_exponent);
287 if (cached_decimal_exponent != exponent) {
288 int adjustment_exponent = exponent - cached_decimal_exponent;
289 DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
290 input.Multiply(adjustment_power);
291 if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
297 error += kDenominator / 2;
301 input.Multiply(cached_power);
307 int error_b = kDenominator / 2;
308 int error_ab = (error == 0 ? 0 : 1);
309 int fixed_error = kDenominator / 2;
310 error += error_b + error_ab + fixed_error;
314 error <<= old_e - input.e();
318 int effective_significand_size =
320 int precision_digits_count =
326 int shift_amount = (precision_digits_count + kDenominatorLog) -
328 input.set_f(input.f() >> shift_amount);
329 input.set_e(input.e() + shift_amount);
332 error = (error >> shift_amount) + 1 + kDenominator;
333 precision_digits_count -= shift_amount;
337 ASSERT(precision_digits_count < 64);
339 uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
340 uint64_t precision_bits = input.f() & precision_bits_mask;
341 uint64_t half_way = one64 << (precision_digits_count - 1);
342 precision_bits *= kDenominator;
343 half_way *= kDenominator;
344 DiyFp rounded_input(input.f() >> precision_digits_count,
345 input.e() + precision_digits_count);
346 if (precision_bits >= half_way + error) {
347 rounded_input.set_f(rounded_input.f() + 1);
353 *result = Double(rounded_input).value();
354 if (half_way - error < precision_bits && precision_bits < half_way + error) {
372 static double BignumStrtod(Vector<const char> buffer,
379 DiyFp upper_boundary = Double(guess).UpperBoundary();
381 ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
382 ASSERT(buffer.length() + exponent > kMinDecimalPower);
383 ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
391 input.AssignDecimalString(buffer);
392 boundary.AssignUInt64(upper_boundary.f());
394 input.MultiplyByPowerOfTen(exponent);
396 boundary.MultiplyByPowerOfTen(-exponent);
398 if (upper_boundary.e() > 0) {
399 boundary.ShiftLeft(upper_boundary.e());
401 input.ShiftLeft(-upper_boundary.e());
404 if (comparison < 0) {
406 }
else if (comparison > 0) {
407 return Double(guess).NextDouble();
408 }
else if ((Double(guess).Significand() & 1) == 0) {
412 return Double(guess).NextDouble();
421 if (trimmed.
length() == 0)
return 0.0;
422 if (trimmed.
length() > kMaxSignificantDecimalDigits) {
423 char significant_buffer[kMaxSignificantDecimalDigits];
424 int significant_exponent;
425 TrimToMaxSignificantDigits(trimmed, exponent,
426 significant_buffer, &significant_exponent);
428 kMaxSignificantDecimalDigits),
429 significant_exponent);
432 if (exponent + trimmed.
length() <= kMinDecimalPower)
return 0.0;
435 if (DoubleStrtod(trimmed, exponent, &guess) ||
436 DiyFpStrtod(trimmed, exponent, &guess)) {
439 return BignumStrtod(trimmed, exponent, guess);
static const int kMaxDecimalExponent
static const int kSignificandSize
static const int kMinDecimalExponent
Vector< T > SubVector(int from, int to)
static int SignificandSizeForOrderOfMagnitude(int order)
#define ASSERT(condition)
static int Compare(const Bignum &a, const Bignum &b)
double Strtod(Vector< const char > buffer, int exponent)
static const int kDecimalExponentDistance
#define V8_2PART_UINT64_C(a, b)
static const int kMaxSignificantBits
static void GetCachedPowerForDecimalExponent(int requested_exponent, DiyFp *power, int *found_exponent)