v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bignum-dtoa.cc
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // 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 <cmath>
29 
30 #include "../include/v8stdint.h"
31 #include "checks.h"
32 #include "utils.h"
33 
34 #include "bignum-dtoa.h"
35 
36 #include "bignum.h"
37 #include "double.h"
38 
39 namespace v8 {
40 namespace internal {
41 
42 static int NormalizedExponent(uint64_t significand, int exponent) {
43  ASSERT(significand != 0);
44  while ((significand & Double::kHiddenBit) == 0) {
45  significand = significand << 1;
46  exponent = exponent - 1;
47  }
48  return exponent;
49 }
50 
51 
52 // Forward declarations:
53 // Returns an estimation of k such that 10^(k-1) <= v < 10^k.
54 static int EstimatePower(int exponent);
55 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
56 // and denominator.
57 static void InitialScaledStartValues(double v,
58  int estimated_power,
59  bool need_boundary_deltas,
60  Bignum* numerator,
61  Bignum* denominator,
62  Bignum* delta_minus,
63  Bignum* delta_plus);
64 // Multiplies numerator/denominator so that its values lies in the range 1-10.
65 // Returns decimal_point s.t.
66 // v = numerator'/denominator' * 10^(decimal_point-1)
67 // where numerator' and denominator' are the values of numerator and
68 // denominator after the call to this function.
69 static void FixupMultiply10(int estimated_power, bool is_even,
70  int* decimal_point,
71  Bignum* numerator, Bignum* denominator,
72  Bignum* delta_minus, Bignum* delta_plus);
73 // Generates digits from the left to the right and stops when the generated
74 // digits yield the shortest decimal representation of v.
75 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
76  Bignum* delta_minus, Bignum* delta_plus,
77  bool is_even,
78  Vector<char> buffer, int* length);
79 // Generates 'requested_digits' after the decimal point.
80 static void BignumToFixed(int requested_digits, int* decimal_point,
81  Bignum* numerator, Bignum* denominator,
82  Vector<char>(buffer), int* length);
83 // Generates 'count' digits of numerator/denominator.
84 // Once 'count' digits have been produced rounds the result depending on the
85 // remainder (remainders of exactly .5 round upwards). Might update the
86 // decimal_point when rounding up (for example for 0.9999).
87 static void GenerateCountedDigits(int count, int* decimal_point,
88  Bignum* numerator, Bignum* denominator,
89  Vector<char>(buffer), int* length);
90 
91 
92 void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
93  Vector<char> buffer, int* length, int* decimal_point) {
94  ASSERT(v > 0);
95  ASSERT(!Double(v).IsSpecial());
96  uint64_t significand = Double(v).Significand();
97  bool is_even = (significand & 1) == 0;
98  int exponent = Double(v).Exponent();
99  int normalized_exponent = NormalizedExponent(significand, exponent);
100  // estimated_power might be too low by 1.
101  int estimated_power = EstimatePower(normalized_exponent);
102 
103  // Shortcut for Fixed.
104  // The requested digits correspond to the digits after the point. If the
105  // number is much too small, then there is no need in trying to get any
106  // digits.
107  if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
108  buffer[0] = '\0';
109  *length = 0;
110  // Set decimal-point to -requested_digits. This is what Gay does.
111  // Note that it should not have any effect anyways since the string is
112  // empty.
113  *decimal_point = -requested_digits;
114  return;
115  }
116 
117  Bignum numerator;
118  Bignum denominator;
119  Bignum delta_minus;
120  Bignum delta_plus;
121  // Make sure the bignum can grow large enough. The smallest double equals
122  // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
123  // The maximum double is 1.7976931348623157e308 which needs fewer than
124  // 308*4 binary digits.
126  bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST);
127  InitialScaledStartValues(v, estimated_power, need_boundary_deltas,
128  &numerator, &denominator,
129  &delta_minus, &delta_plus);
130  // We now have v = (numerator / denominator) * 10^estimated_power.
131  FixupMultiply10(estimated_power, is_even, decimal_point,
132  &numerator, &denominator,
133  &delta_minus, &delta_plus);
134  // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
135  // 1 <= (numerator + delta_plus) / denominator < 10
136  switch (mode) {
138  GenerateShortestDigits(&numerator, &denominator,
139  &delta_minus, &delta_plus,
140  is_even, buffer, length);
141  break;
142  case BIGNUM_DTOA_FIXED:
143  BignumToFixed(requested_digits, decimal_point,
144  &numerator, &denominator,
145  buffer, length);
146  break;
148  GenerateCountedDigits(requested_digits, decimal_point,
149  &numerator, &denominator,
150  buffer, length);
151  break;
152  default:
153  UNREACHABLE();
154  }
155  buffer[*length] = '\0';
156 }
157 
158 
159 // The procedure starts generating digits from the left to the right and stops
160 // when the generated digits yield the shortest decimal representation of v. A
161 // decimal representation of v is a number lying closer to v than to any other
162 // double, so it converts to v when read.
163 //
164 // This is true if d, the decimal representation, is between m- and m+, the
165 // upper and lower boundaries. d must be strictly between them if !is_even.
166 // m- := (numerator - delta_minus) / denominator
167 // m+ := (numerator + delta_plus) / denominator
168 //
169 // Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
170 // If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
171 // will be produced. This should be the standard precondition.
172 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
173  Bignum* delta_minus, Bignum* delta_plus,
174  bool is_even,
175  Vector<char> buffer, int* length) {
176  // Small optimization: if delta_minus and delta_plus are the same just reuse
177  // one of the two bignums.
178  if (Bignum::Equal(*delta_minus, *delta_plus)) {
179  delta_plus = delta_minus;
180  }
181  *length = 0;
182  while (true) {
183  uint16_t digit;
184  digit = numerator->DivideModuloIntBignum(*denominator);
185  ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
186  // digit = numerator / denominator (integer division).
187  // numerator = numerator % denominator.
188  buffer[(*length)++] = digit + '0';
189 
190  // Can we stop already?
191  // If the remainder of the division is less than the distance to the lower
192  // boundary we can stop. In this case we simply round down (discarding the
193  // remainder).
194  // Similarly we test if we can round up (using the upper boundary).
195  bool in_delta_room_minus;
196  bool in_delta_room_plus;
197  if (is_even) {
198  in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
199  } else {
200  in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
201  }
202  if (is_even) {
203  in_delta_room_plus =
204  Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
205  } else {
206  in_delta_room_plus =
207  Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
208  }
209  if (!in_delta_room_minus && !in_delta_room_plus) {
210  // Prepare for next iteration.
211  numerator->Times10();
212  delta_minus->Times10();
213  // We optimized delta_plus to be equal to delta_minus (if they share the
214  // same value). So don't multiply delta_plus if they point to the same
215  // object.
216  if (delta_minus != delta_plus) {
217  delta_plus->Times10();
218  }
219  } else if (in_delta_room_minus && in_delta_room_plus) {
220  // Let's see if 2*numerator < denominator.
221  // If yes, then the next digit would be < 5 and we can round down.
222  int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
223  if (compare < 0) {
224  // Remaining digits are less than .5. -> Round down (== do nothing).
225  } else if (compare > 0) {
226  // Remaining digits are more than .5 of denominator. -> Round up.
227  // Note that the last digit could not be a '9' as otherwise the whole
228  // loop would have stopped earlier.
229  // We still have an assert here in case the preconditions were not
230  // satisfied.
231  ASSERT(buffer[(*length) - 1] != '9');
232  buffer[(*length) - 1]++;
233  } else {
234  // Halfway case.
235  // TODO(floitsch): need a way to solve half-way cases.
236  // For now let's round towards even (since this is what Gay seems to
237  // do).
238 
239  if ((buffer[(*length) - 1] - '0') % 2 == 0) {
240  // Round down => Do nothing.
241  } else {
242  ASSERT(buffer[(*length) - 1] != '9');
243  buffer[(*length) - 1]++;
244  }
245  }
246  return;
247  } else if (in_delta_room_minus) {
248  // Round down (== do nothing).
249  return;
250  } else { // in_delta_room_plus
251  // Round up.
252  // Note again that the last digit could not be '9' since this would have
253  // stopped the loop earlier.
254  // We still have an ASSERT here, in case the preconditions were not
255  // satisfied.
256  ASSERT(buffer[(*length) -1] != '9');
257  buffer[(*length) - 1]++;
258  return;
259  }
260  }
261 }
262 
263 
264 // Let v = numerator / denominator < 10.
265 // Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
266 // from left to right. Once 'count' digits have been produced we decide wether
267 // to round up or down. Remainders of exactly .5 round upwards. Numbers such
268 // as 9.999999 propagate a carry all the way, and change the
269 // exponent (decimal_point), when rounding upwards.
270 static void GenerateCountedDigits(int count, int* decimal_point,
271  Bignum* numerator, Bignum* denominator,
272  Vector<char>(buffer), int* length) {
273  ASSERT(count >= 0);
274  for (int i = 0; i < count - 1; ++i) {
275  uint16_t digit;
276  digit = numerator->DivideModuloIntBignum(*denominator);
277  ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
278  // digit = numerator / denominator (integer division).
279  // numerator = numerator % denominator.
280  buffer[i] = digit + '0';
281  // Prepare for next iteration.
282  numerator->Times10();
283  }
284  // Generate the last digit.
285  uint16_t digit;
286  digit = numerator->DivideModuloIntBignum(*denominator);
287  if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
288  digit++;
289  }
290  buffer[count - 1] = digit + '0';
291  // Correct bad digits (in case we had a sequence of '9's). Propagate the
292  // carry until we hat a non-'9' or til we reach the first digit.
293  for (int i = count - 1; i > 0; --i) {
294  if (buffer[i] != '0' + 10) break;
295  buffer[i] = '0';
296  buffer[i - 1]++;
297  }
298  if (buffer[0] == '0' + 10) {
299  // Propagate a carry past the top place.
300  buffer[0] = '1';
301  (*decimal_point)++;
302  }
303  *length = count;
304 }
305 
306 
307 // Generates 'requested_digits' after the decimal point. It might omit
308 // trailing '0's. If the input number is too small then no digits at all are
309 // generated (ex.: 2 fixed digits for 0.00001).
310 //
311 // Input verifies: 1 <= (numerator + delta) / denominator < 10.
312 static void BignumToFixed(int requested_digits, int* decimal_point,
313  Bignum* numerator, Bignum* denominator,
314  Vector<char>(buffer), int* length) {
315  // Note that we have to look at more than just the requested_digits, since
316  // a number could be rounded up. Example: v=0.5 with requested_digits=0.
317  // Even though the power of v equals 0 we can't just stop here.
318  if (-(*decimal_point) > requested_digits) {
319  // The number is definitively too small.
320  // Ex: 0.001 with requested_digits == 1.
321  // Set decimal-point to -requested_digits. This is what Gay does.
322  // Note that it should not have any effect anyways since the string is
323  // empty.
324  *decimal_point = -requested_digits;
325  *length = 0;
326  return;
327  } else if (-(*decimal_point) == requested_digits) {
328  // We only need to verify if the number rounds down or up.
329  // Ex: 0.04 and 0.06 with requested_digits == 1.
330  ASSERT(*decimal_point == -requested_digits);
331  // Initially the fraction lies in range (1, 10]. Multiply the denominator
332  // by 10 so that we can compare more easily.
333  denominator->Times10();
334  if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
335  // If the fraction is >= 0.5 then we have to include the rounded
336  // digit.
337  buffer[0] = '1';
338  *length = 1;
339  (*decimal_point)++;
340  } else {
341  // Note that we caught most of similar cases earlier.
342  *length = 0;
343  }
344  return;
345  } else {
346  // The requested digits correspond to the digits after the point.
347  // The variable 'needed_digits' includes the digits before the point.
348  int needed_digits = (*decimal_point) + requested_digits;
349  GenerateCountedDigits(needed_digits, decimal_point,
350  numerator, denominator,
351  buffer, length);
352  }
353 }
354 
355 
356 // Returns an estimation of k such that 10^(k-1) <= v < 10^k where
357 // v = f * 2^exponent and 2^52 <= f < 2^53.
358 // v is hence a normalized double with the given exponent. The output is an
359 // approximation for the exponent of the decimal approimation .digits * 10^k.
360 //
361 // The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
362 // Note: this property holds for v's upper boundary m+ too.
363 // 10^k <= m+ < 10^k+1.
364 // (see explanation below).
365 //
366 // Examples:
367 // EstimatePower(0) => 16
368 // EstimatePower(-52) => 0
369 //
370 // Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
371 static int EstimatePower(int exponent) {
372  // This function estimates log10 of v where v = f*2^e (with e == exponent).
373  // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
374  // Note that f is bounded by its container size. Let p = 53 (the double's
375  // significand size). Then 2^(p-1) <= f < 2^p.
376  //
377  // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
378  // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
379  // The computed number undershoots by less than 0.631 (when we compute log3
380  // and not log10).
381  //
382  // Optimization: since we only need an approximated result this computation
383  // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
384  // not really measurable, though.
385  //
386  // Since we want to avoid overshooting we decrement by 1e10 so that
387  // floating-point imprecisions don't affect us.
388  //
389  // Explanation for v's boundary m+: the computation takes advantage of
390  // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
391  // (even for denormals where the delta can be much more important).
392 
393  const double k1Log10 = 0.30102999566398114; // 1/lg(10)
394 
395  // For doubles len(f) == 53 (don't forget the hidden bit).
396  const int kSignificandSize = 53;
397  double estimate =
398  std::ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
399  return static_cast<int>(estimate);
400 }
401 
402 
403 // See comments for InitialScaledStartValues.
404 static void InitialScaledStartValuesPositiveExponent(
405  double v, int estimated_power, bool need_boundary_deltas,
406  Bignum* numerator, Bignum* denominator,
407  Bignum* delta_minus, Bignum* delta_plus) {
408  // A positive exponent implies a positive power.
409  ASSERT(estimated_power >= 0);
410  // Since the estimated_power is positive we simply multiply the denominator
411  // by 10^estimated_power.
412 
413  // numerator = v.
414  numerator->AssignUInt64(Double(v).Significand());
415  numerator->ShiftLeft(Double(v).Exponent());
416  // denominator = 10^estimated_power.
417  denominator->AssignPowerUInt16(10, estimated_power);
418 
419  if (need_boundary_deltas) {
420  // Introduce a common denominator so that the deltas to the boundaries are
421  // integers.
422  denominator->ShiftLeft(1);
423  numerator->ShiftLeft(1);
424  // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
425  // denominator (of 2) delta_plus equals 2^e.
426  delta_plus->AssignUInt16(1);
427  delta_plus->ShiftLeft(Double(v).Exponent());
428  // Same for delta_minus (with adjustments below if f == 2^p-1).
429  delta_minus->AssignUInt16(1);
430  delta_minus->ShiftLeft(Double(v).Exponent());
431 
432  // If the significand (without the hidden bit) is 0, then the lower
433  // boundary is closer than just half a ulp (unit in the last place).
434  // There is only one exception: if the next lower number is a denormal then
435  // the distance is 1 ulp. This cannot be the case for exponent >= 0 (but we
436  // have to test it in the other function where exponent < 0).
437  uint64_t v_bits = Double(v).AsUint64();
438  if ((v_bits & Double::kSignificandMask) == 0) {
439  // The lower boundary is closer at half the distance of "normal" numbers.
440  // Increase the common denominator and adapt all but the delta_minus.
441  denominator->ShiftLeft(1); // *2
442  numerator->ShiftLeft(1); // *2
443  delta_plus->ShiftLeft(1); // *2
444  }
445  }
446 }
447 
448 
449 // See comments for InitialScaledStartValues
450 static void InitialScaledStartValuesNegativeExponentPositivePower(
451  double v, int estimated_power, bool need_boundary_deltas,
452  Bignum* numerator, Bignum* denominator,
453  Bignum* delta_minus, Bignum* delta_plus) {
454  uint64_t significand = Double(v).Significand();
455  int exponent = Double(v).Exponent();
456  // v = f * 2^e with e < 0, and with estimated_power >= 0.
457  // This means that e is close to 0 (have a look at how estimated_power is
458  // computed).
459 
460  // numerator = significand
461  // since v = significand * 2^exponent this is equivalent to
462  // numerator = v * / 2^-exponent
463  numerator->AssignUInt64(significand);
464  // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
465  denominator->AssignPowerUInt16(10, estimated_power);
466  denominator->ShiftLeft(-exponent);
467 
468  if (need_boundary_deltas) {
469  // Introduce a common denominator so that the deltas to the boundaries are
470  // integers.
471  denominator->ShiftLeft(1);
472  numerator->ShiftLeft(1);
473  // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
474  // denominator (of 2) delta_plus equals 2^e.
475  // Given that the denominator already includes v's exponent the distance
476  // to the boundaries is simply 1.
477  delta_plus->AssignUInt16(1);
478  // Same for delta_minus (with adjustments below if f == 2^p-1).
479  delta_minus->AssignUInt16(1);
480 
481  // If the significand (without the hidden bit) is 0, then the lower
482  // boundary is closer than just one ulp (unit in the last place).
483  // There is only one exception: if the next lower number is a denormal
484  // then the distance is 1 ulp. Since the exponent is close to zero
485  // (otherwise estimated_power would have been negative) this cannot happen
486  // here either.
487  uint64_t v_bits = Double(v).AsUint64();
488  if ((v_bits & Double::kSignificandMask) == 0) {
489  // The lower boundary is closer at half the distance of "normal" numbers.
490  // Increase the denominator and adapt all but the delta_minus.
491  denominator->ShiftLeft(1); // *2
492  numerator->ShiftLeft(1); // *2
493  delta_plus->ShiftLeft(1); // *2
494  }
495  }
496 }
497 
498 
499 // See comments for InitialScaledStartValues
500 static void InitialScaledStartValuesNegativeExponentNegativePower(
501  double v, int estimated_power, bool need_boundary_deltas,
502  Bignum* numerator, Bignum* denominator,
503  Bignum* delta_minus, Bignum* delta_plus) {
504  const uint64_t kMinimalNormalizedExponent =
505  V8_2PART_UINT64_C(0x00100000, 00000000);
506  uint64_t significand = Double(v).Significand();
507  int exponent = Double(v).Exponent();
508  // Instead of multiplying the denominator with 10^estimated_power we
509  // multiply all values (numerator and deltas) by 10^-estimated_power.
510 
511  // Use numerator as temporary container for power_ten.
512  Bignum* power_ten = numerator;
513  power_ten->AssignPowerUInt16(10, -estimated_power);
514 
515  if (need_boundary_deltas) {
516  // Since power_ten == numerator we must make a copy of 10^estimated_power
517  // before we complete the computation of the numerator.
518  // delta_plus = delta_minus = 10^estimated_power
519  delta_plus->AssignBignum(*power_ten);
520  delta_minus->AssignBignum(*power_ten);
521  }
522 
523  // numerator = significand * 2 * 10^-estimated_power
524  // since v = significand * 2^exponent this is equivalent to
525  // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
526  // Remember: numerator has been abused as power_ten. So no need to assign it
527  // to itself.
528  ASSERT(numerator == power_ten);
529  numerator->MultiplyByUInt64(significand);
530 
531  // denominator = 2 * 2^-exponent with exponent < 0.
532  denominator->AssignUInt16(1);
533  denominator->ShiftLeft(-exponent);
534 
535  if (need_boundary_deltas) {
536  // Introduce a common denominator so that the deltas to the boundaries are
537  // integers.
538  numerator->ShiftLeft(1);
539  denominator->ShiftLeft(1);
540  // With this shift the boundaries have their correct value, since
541  // delta_plus = 10^-estimated_power, and
542  // delta_minus = 10^-estimated_power.
543  // These assignments have been done earlier.
544 
545  // The special case where the lower boundary is twice as close.
546  // This time we have to look out for the exception too.
547  uint64_t v_bits = Double(v).AsUint64();
548  if ((v_bits & Double::kSignificandMask) == 0 &&
549  // The only exception where a significand == 0 has its boundaries at
550  // "normal" distances:
551  (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent) {
552  numerator->ShiftLeft(1); // *2
553  denominator->ShiftLeft(1); // *2
554  delta_plus->ShiftLeft(1); // *2
555  }
556  }
557 }
558 
559 
560 // Let v = significand * 2^exponent.
561 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
562 // and denominator. The functions GenerateShortestDigits and
563 // GenerateCountedDigits will then convert this ratio to its decimal
564 // representation d, with the required accuracy.
565 // Then d * 10^estimated_power is the representation of v.
566 // (Note: the fraction and the estimated_power might get adjusted before
567 // generating the decimal representation.)
568 //
569 // The initial start values consist of:
570 // - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
571 // - a scaled (common) denominator.
572 // optionally (used by GenerateShortestDigits to decide if it has the shortest
573 // decimal converting back to v):
574 // - v - m-: the distance to the lower boundary.
575 // - m+ - v: the distance to the upper boundary.
576 //
577 // v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
578 //
579 // Let ep == estimated_power, then the returned values will satisfy:
580 // v / 10^ep = numerator / denominator.
581 // v's boundarys m- and m+:
582 // m- / 10^ep == v / 10^ep - delta_minus / denominator
583 // m+ / 10^ep == v / 10^ep + delta_plus / denominator
584 // Or in other words:
585 // m- == v - delta_minus * 10^ep / denominator;
586 // m+ == v + delta_plus * 10^ep / denominator;
587 //
588 // Since 10^(k-1) <= v < 10^k (with k == estimated_power)
589 // or 10^k <= v < 10^(k+1)
590 // we then have 0.1 <= numerator/denominator < 1
591 // or 1 <= numerator/denominator < 10
592 //
593 // It is then easy to kickstart the digit-generation routine.
594 //
595 // The boundary-deltas are only filled if need_boundary_deltas is set.
596 static void InitialScaledStartValues(double v,
597  int estimated_power,
598  bool need_boundary_deltas,
599  Bignum* numerator,
600  Bignum* denominator,
601  Bignum* delta_minus,
602  Bignum* delta_plus) {
603  if (Double(v).Exponent() >= 0) {
604  InitialScaledStartValuesPositiveExponent(
605  v, estimated_power, need_boundary_deltas,
606  numerator, denominator, delta_minus, delta_plus);
607  } else if (estimated_power >= 0) {
608  InitialScaledStartValuesNegativeExponentPositivePower(
609  v, estimated_power, need_boundary_deltas,
610  numerator, denominator, delta_minus, delta_plus);
611  } else {
612  InitialScaledStartValuesNegativeExponentNegativePower(
613  v, estimated_power, need_boundary_deltas,
614  numerator, denominator, delta_minus, delta_plus);
615  }
616 }
617 
618 
619 // This routine multiplies numerator/denominator so that its values lies in the
620 // range 1-10. That is after a call to this function we have:
621 // 1 <= (numerator + delta_plus) /denominator < 10.
622 // Let numerator the input before modification and numerator' the argument
623 // after modification, then the output-parameter decimal_point is such that
624 // numerator / denominator * 10^estimated_power ==
625 // numerator' / denominator' * 10^(decimal_point - 1)
626 // In some cases estimated_power was too low, and this is already the case. We
627 // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
628 // estimated_power) but do not touch the numerator or denominator.
629 // Otherwise the routine multiplies the numerator and the deltas by 10.
630 static void FixupMultiply10(int estimated_power, bool is_even,
631  int* decimal_point,
632  Bignum* numerator, Bignum* denominator,
633  Bignum* delta_minus, Bignum* delta_plus) {
634  bool in_range;
635  if (is_even) {
636  // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
637  // are rounded to the closest floating-point number with even significand.
638  in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
639  } else {
640  in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
641  }
642  if (in_range) {
643  // Since numerator + delta_plus >= denominator we already have
644  // 1 <= numerator/denominator < 10. Simply update the estimated_power.
645  *decimal_point = estimated_power + 1;
646  } else {
647  *decimal_point = estimated_power;
648  numerator->Times10();
649  if (Bignum::Equal(*delta_minus, *delta_plus)) {
650  delta_minus->Times10();
651  delta_plus->AssignBignum(*delta_minus);
652  } else {
653  delta_minus->Times10();
654  delta_plus->Times10();
655  }
656  }
657 }
658 
659 } } // namespace v8::internal
uint64_t Significand() const
Definition: double.h:110
static const uint64_t kExponentMask
Definition: double.h:44
static const uint64_t kHiddenBit
Definition: double.h:47
int Exponent() const
Definition: double.h:101
#define ASSERT(condition)
Definition: checks.h:329
unsigned short uint16_t
Definition: unicode.cc:46
#define UNREACHABLE()
Definition: checks.h:52
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
static int PlusCompare(const Bignum &a, const Bignum &b, const Bignum &c)
Definition: bignum.cc:636
static bool Equal(const Bignum &a, const Bignum &b)
Definition: bignum.h:72
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, Vector< char > buffer, int *length, int *decimal_point)
Definition: bignum-dtoa.cc:92
static bool Less(const Bignum &a, const Bignum &b)
Definition: bignum.h:78
#define V8_2PART_UINT64_C(a, b)
Definition: globals.h:226
static const uint64_t kSignificandMask
Definition: double.h:45
static bool LessEqual(const Bignum &a, const Bignum &b)
Definition: bignum.h:75
static const int kMaxSignificantBits
Definition: bignum.h:39