blob: b32abd97d7929ef83d6e4765b5feea7970ba48be [file] [log] [blame]
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001// Copyright 2011 the V8 project authors. All rights reserved.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdarg.h>
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000029#include <limits>
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000030
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000031#ifndef V8_INFINITY
32#define V8_INFINITY std::numeric_limits<double>::infinity()
33#endif
34
35#include "utils.h"
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000036
37#include "strtod.h"
ager@chromium.org01fe7df2010-11-10 11:59:11 +000038#include "bignum.h"
lrn@chromium.org303ada72010-10-27 09:33:13 +000039#include "cached-powers.h"
40#include "double.h"
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000041
42namespace v8 {
43namespace internal {
44
45// 2^53 = 9007199254740992.
46// Any integer with at most 15 decimal digits will hence fit into a double
47// (which has a 53bit significand) without loss of precision.
48static const int kMaxExactDoubleIntegerDecimalDigits = 15;
lrn@chromium.org303ada72010-10-27 09:33:13 +000049// 2^64 = 18446744073709551616 > 10^19
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000050static const int kMaxUint64DecimalDigits = 19;
lrn@chromium.org303ada72010-10-27 09:33:13 +000051
vegorov@chromium.org42841962010-10-18 11:18:59 +000052// Max double: 1.7976931348623157 x 10^308
53// Min non-zero double: 4.9406564584124654 x 10^-324
54// Any x >= 10^309 is interpreted as +infinity.
55// Any x <= 10^-324 is interpreted as 0.
56// Note that 2.5e-324 (despite being smaller than the min double) will be read
57// as non-zero (equal to the min non-zero double).
58static const int kMaxDecimalPower = 309;
59static const int kMinDecimalPower = -324;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000060
lrn@chromium.org303ada72010-10-27 09:33:13 +000061// 2^64 = 18446744073709551616
62static const uint64_t kMaxUint64 = V8_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF);
63
64
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000065static const double exact_powers_of_ten[] = {
66 1.0, // 10^0
67 10.0,
68 100.0,
69 1000.0,
70 10000.0,
71 100000.0,
72 1000000.0,
73 10000000.0,
74 100000000.0,
75 1000000000.0,
76 10000000000.0, // 10^10
77 100000000000.0,
78 1000000000000.0,
79 10000000000000.0,
80 100000000000000.0,
81 1000000000000000.0,
82 10000000000000000.0,
83 100000000000000000.0,
84 1000000000000000000.0,
85 10000000000000000000.0,
86 100000000000000000000.0, // 10^20
87 1000000000000000000000.0,
88 // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
89 10000000000000000000000.0
90};
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000091static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
92
ager@chromium.org01fe7df2010-11-10 11:59:11 +000093// Maximum number of significant digits in the decimal representation.
94// In fact the value is 772 (see conversions.cc), but to give us some margin
95// we round up to 780.
96static const int kMaxSignificantDecimalDigits = 780;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000097
vegorov@chromium.org42841962010-10-18 11:18:59 +000098static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
99 for (int i = 0; i < buffer.length(); i++) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000100 if (buffer[i] != '0') {
lrn@chromium.org303ada72010-10-27 09:33:13 +0000101 return buffer.SubVector(i, buffer.length());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000102 }
103 }
vegorov@chromium.org42841962010-10-18 11:18:59 +0000104 return Vector<const char>(buffer.start(), 0);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000105}
106
107
vegorov@chromium.org42841962010-10-18 11:18:59 +0000108static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
109 for (int i = buffer.length() - 1; i >= 0; --i) {
110 if (buffer[i] != '0') {
lrn@chromium.org303ada72010-10-27 09:33:13 +0000111 return buffer.SubVector(0, i + 1);
vegorov@chromium.org42841962010-10-18 11:18:59 +0000112 }
113 }
114 return Vector<const char>(buffer.start(), 0);
115}
116
117
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000118static void TrimToMaxSignificantDigits(Vector<const char> buffer,
119 int exponent,
120 char* significant_buffer,
121 int* significant_exponent) {
122 for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
123 significant_buffer[i] = buffer[i];
124 }
125 // The input buffer has been trimmed. Therefore the last digit must be
126 // different from '0'.
127 ASSERT(buffer[buffer.length() - 1] != '0');
128 // Set the last digit to be non-zero. This is sufficient to guarantee
129 // correct rounding.
130 significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
131 *significant_exponent =
132 exponent + (buffer.length() - kMaxSignificantDecimalDigits);
133}
134
lrn@chromium.org303ada72010-10-27 09:33:13 +0000135// Reads digits from the buffer and converts them to a uint64.
136// Reads in as many digits as fit into a uint64.
137// When the string starts with "1844674407370955161" no further digit is read.
138// Since 2^64 = 18446744073709551616 it would still be possible read another
139// digit if it was less or equal than 6, but this would complicate the code.
140static uint64_t ReadUint64(Vector<const char> buffer,
141 int* number_of_read_digits) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000142 uint64_t result = 0;
lrn@chromium.org303ada72010-10-27 09:33:13 +0000143 int i = 0;
144 while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
145 int digit = buffer[i++] - '0';
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000146 ASSERT(0 <= digit && digit <= 9);
147 result = 10 * result + digit;
148 }
lrn@chromium.org303ada72010-10-27 09:33:13 +0000149 *number_of_read_digits = i;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000150 return result;
151}
152
153
lrn@chromium.org303ada72010-10-27 09:33:13 +0000154// Reads a DiyFp from the buffer.
155// The returned DiyFp is not necessarily normalized.
156// If remaining_decimals is zero then the returned DiyFp is accurate.
157// Otherwise it has been rounded and has error of at most 1/2 ulp.
158static void ReadDiyFp(Vector<const char> buffer,
159 DiyFp* result,
160 int* remaining_decimals) {
161 int read_digits;
162 uint64_t significand = ReadUint64(buffer, &read_digits);
163 if (buffer.length() == read_digits) {
164 *result = DiyFp(significand, 0);
165 *remaining_decimals = 0;
166 } else {
167 // Round the significand.
168 if (buffer[read_digits] >= '5') {
169 significand++;
170 }
171 // Compute the binary exponent.
172 int exponent = 0;
173 *result = DiyFp(significand, exponent);
174 *remaining_decimals = buffer.length() - read_digits;
175 }
176}
177
178
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000179static bool DoubleStrtod(Vector<const char> trimmed,
180 int exponent,
181 double* result) {
182#if (defined(V8_TARGET_ARCH_IA32) || defined(USE_SIMULATOR)) && !defined(WIN32)
183 // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
184 // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
185 // result is not accurate.
186 // We know that Windows32 uses 64 bits and is therefore accurate.
187 // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
188 // the same problem.
189 return false;
190#endif
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000191 if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
lrn@chromium.org303ada72010-10-27 09:33:13 +0000192 int read_digits;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000193 // The trimmed input fits into a double.
194 // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
195 // can compute the result-double simply by multiplying (resp. dividing) the
196 // two numbers.
197 // This is possible because IEEE guarantees that floating-point operations
198 // return the best possible approximation.
199 if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
200 // 10^-exponent fits into a double.
lrn@chromium.org303ada72010-10-27 09:33:13 +0000201 *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
202 ASSERT(read_digits == trimmed.length());
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000203 *result /= exact_powers_of_ten[-exponent];
204 return true;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000205 }
206 if (0 <= exponent && exponent < kExactPowersOfTenSize) {
207 // 10^exponent fits into a double.
lrn@chromium.org303ada72010-10-27 09:33:13 +0000208 *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
209 ASSERT(read_digits == trimmed.length());
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000210 *result *= exact_powers_of_ten[exponent];
211 return true;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000212 }
213 int remaining_digits =
214 kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
215 if ((0 <= exponent) &&
216 (exponent - remaining_digits < kExactPowersOfTenSize)) {
217 // The trimmed string was short and we can multiply it with
218 // 10^remaining_digits. As a result the remaining exponent now fits
219 // into a double too.
lrn@chromium.org303ada72010-10-27 09:33:13 +0000220 *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
221 ASSERT(read_digits == trimmed.length());
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000222 *result *= exact_powers_of_ten[remaining_digits];
223 *result *= exact_powers_of_ten[exponent - remaining_digits];
224 return true;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000225 }
226 }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000227 return false;
228}
229
230
lrn@chromium.org303ada72010-10-27 09:33:13 +0000231// Returns 10^exponent as an exact DiyFp.
232// The given exponent must be in the range [1; kDecimalExponentDistance[.
233static DiyFp AdjustmentPowerOfTen(int exponent) {
234 ASSERT(0 < exponent);
235 ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
236 // Simply hardcode the remaining powers for the given decimal exponent
237 // distance.
238 ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
239 switch (exponent) {
240 case 1: return DiyFp(V8_2PART_UINT64_C(0xa0000000, 00000000), -60);
241 case 2: return DiyFp(V8_2PART_UINT64_C(0xc8000000, 00000000), -57);
242 case 3: return DiyFp(V8_2PART_UINT64_C(0xfa000000, 00000000), -54);
243 case 4: return DiyFp(V8_2PART_UINT64_C(0x9c400000, 00000000), -50);
244 case 5: return DiyFp(V8_2PART_UINT64_C(0xc3500000, 00000000), -47);
245 case 6: return DiyFp(V8_2PART_UINT64_C(0xf4240000, 00000000), -44);
246 case 7: return DiyFp(V8_2PART_UINT64_C(0x98968000, 00000000), -40);
247 default:
248 UNREACHABLE();
249 return DiyFp(0, 0);
250 }
251}
252
253
254// If the function returns true then the result is the correct double.
255// Otherwise it is either the correct double or the double that is just below
256// the correct double.
257static bool DiyFpStrtod(Vector<const char> buffer,
258 int exponent,
259 double* result) {
260 DiyFp input;
261 int remaining_decimals;
262 ReadDiyFp(buffer, &input, &remaining_decimals);
263 // Since we may have dropped some digits the input is not accurate.
264 // If remaining_decimals is different than 0 than the error is at most
265 // .5 ulp (unit in the last place).
266 // We don't want to deal with fractions and therefore keep a common
267 // denominator.
268 const int kDenominatorLog = 3;
269 const int kDenominator = 1 << kDenominatorLog;
270 // Move the remaining decimals into the exponent.
271 exponent += remaining_decimals;
272 int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
273
274 int old_e = input.e();
275 input.Normalize();
276 error <<= old_e - input.e();
277
278 ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
279 if (exponent < PowersOfTenCache::kMinDecimalExponent) {
280 *result = 0.0;
281 return true;
282 }
283 DiyFp cached_power;
284 int cached_decimal_exponent;
285 PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent,
286 &cached_power,
287 &cached_decimal_exponent);
288
289 if (cached_decimal_exponent != exponent) {
290 int adjustment_exponent = exponent - cached_decimal_exponent;
291 DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
292 input.Multiply(adjustment_power);
293 if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
294 // The product of input with the adjustment power fits into a 64 bit
295 // integer.
296 ASSERT(DiyFp::kSignificandSize == 64);
297 } else {
298 // The adjustment power is exact. There is hence only an error of 0.5.
299 error += kDenominator / 2;
300 }
301 }
302
303 input.Multiply(cached_power);
304 // The error introduced by a multiplication of a*b equals
305 // error_a + error_b + error_a*error_b/2^64 + 0.5
306 // Substituting a with 'input' and b with 'cached_power' we have
307 // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp),
308 // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
309 int error_b = kDenominator / 2;
310 int error_ab = (error == 0 ? 0 : 1); // We round up to 1.
311 int fixed_error = kDenominator / 2;
312 error += error_b + error_ab + fixed_error;
313
314 old_e = input.e();
315 input.Normalize();
316 error <<= old_e - input.e();
317
318 // See if the double's significand changes if we add/subtract the error.
319 int order_of_magnitude = DiyFp::kSignificandSize + input.e();
320 int effective_significand_size =
321 Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
322 int precision_digits_count =
323 DiyFp::kSignificandSize - effective_significand_size;
324 if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
325 // This can only happen for very small denormals. In this case the
326 // half-way multiplied by the denominator exceeds the range of an uint64.
327 // Simply shift everything to the right.
328 int shift_amount = (precision_digits_count + kDenominatorLog) -
329 DiyFp::kSignificandSize + 1;
330 input.set_f(input.f() >> shift_amount);
331 input.set_e(input.e() + shift_amount);
332 // We add 1 for the lost precision of error, and kDenominator for
333 // the lost precision of input.f().
334 error = (error >> shift_amount) + 1 + kDenominator;
335 precision_digits_count -= shift_amount;
336 }
337 // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
338 ASSERT(DiyFp::kSignificandSize == 64);
339 ASSERT(precision_digits_count < 64);
340 uint64_t one64 = 1;
341 uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
342 uint64_t precision_bits = input.f() & precision_bits_mask;
343 uint64_t half_way = one64 << (precision_digits_count - 1);
344 precision_bits *= kDenominator;
345 half_way *= kDenominator;
346 DiyFp rounded_input(input.f() >> precision_digits_count,
347 input.e() + precision_digits_count);
348 if (precision_bits >= half_way + error) {
349 rounded_input.set_f(rounded_input.f() + 1);
350 }
351 // If the last_bits are too close to the half-way case than we are too
352 // inaccurate and round down. In this case we return false so that we can
353 // fall back to a more precise algorithm.
354
355 *result = Double(rounded_input).value();
356 if (half_way - error < precision_bits && precision_bits < half_way + error) {
357 // Too imprecise. The caller will have to fall back to a slower version.
358 // However the returned number is guaranteed to be either the correct
359 // double, or the next-lower double.
360 return false;
361 } else {
362 return true;
363 }
364}
365
366
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000367// Returns the correct double for the buffer*10^exponent.
368// The variable guess should be a close guess that is either the correct double
369// or its lower neighbor (the nearest double less than the correct one).
370// Preconditions:
371// buffer.length() + exponent <= kMaxDecimalPower + 1
372// buffer.length() + exponent > kMinDecimalPower
373// buffer.length() <= kMaxDecimalSignificantDigits
374static double BignumStrtod(Vector<const char> buffer,
375 int exponent,
376 double guess) {
377 if (guess == V8_INFINITY) {
378 return guess;
379 }
380
381 DiyFp upper_boundary = Double(guess).UpperBoundary();
382
383 ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
384 ASSERT(buffer.length() + exponent > kMinDecimalPower);
385 ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
386 // Make sure that the Bignum will be able to hold all our numbers.
387 // Our Bignum implementation has a separate field for exponents. Shifts will
388 // consume at most one bigit (< 64 bits).
389 // ln(10) == 3.3219...
390 ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
391 Bignum input;
392 Bignum boundary;
393 input.AssignDecimalString(buffer);
394 boundary.AssignUInt64(upper_boundary.f());
395 if (exponent >= 0) {
396 input.MultiplyByPowerOfTen(exponent);
397 } else {
398 boundary.MultiplyByPowerOfTen(-exponent);
399 }
400 if (upper_boundary.e() > 0) {
401 boundary.ShiftLeft(upper_boundary.e());
402 } else {
403 input.ShiftLeft(-upper_boundary.e());
404 }
405 int comparison = Bignum::Compare(input, boundary);
406 if (comparison < 0) {
407 return guess;
408 } else if (comparison > 0) {
409 return Double(guess).NextDouble();
410 } else if ((Double(guess).Significand() & 1) == 0) {
411 // Round towards even.
412 return guess;
413 } else {
414 return Double(guess).NextDouble();
415 }
416}
417
418
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000419double Strtod(Vector<const char> buffer, int exponent) {
420 Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
421 Vector<const char> trimmed = TrimTrailingZeros(left_trimmed);
422 exponent += left_trimmed.length() - trimmed.length();
423 if (trimmed.length() == 0) return 0.0;
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000424 if (trimmed.length() > kMaxSignificantDecimalDigits) {
425 char significant_buffer[kMaxSignificantDecimalDigits];
426 int significant_exponent;
427 TrimToMaxSignificantDigits(trimmed, exponent,
428 significant_buffer, &significant_exponent);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000429 return Strtod(Vector<const char>(significant_buffer,
430 kMaxSignificantDecimalDigits),
431 significant_exponent);
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000432 }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000433 if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) return V8_INFINITY;
434 if (exponent + trimmed.length() <= kMinDecimalPower) return 0.0;
lrn@chromium.org303ada72010-10-27 09:33:13 +0000435
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000436 double guess;
437 if (DoubleStrtod(trimmed, exponent, &guess) ||
438 DiyFpStrtod(trimmed, exponent, &guess)) {
439 return guess;
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000440 }
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000441 return BignumStrtod(trimmed, exponent, guess);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000442}
443
444} } // namespace v8::internal