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