155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
44a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org#include <cmath>
64a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "include/v8stdint.h"
85de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/logging.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
1055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bignum-dtoa.h"
124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bignum.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/double.h"
154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comnamespace v8 {
174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comnamespace internal {
184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic int NormalizedExponent(uint64_t significand, int exponent) {
20e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(significand != 0);
214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  while ((significand & Double::kHiddenBit) == 0) {
224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    significand = significand << 1;
234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    exponent = exponent - 1;
244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return exponent;
264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Forward declarations:
304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Returns an estimation of k such that 10^(k-1) <= v < 10^k.
314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic int EstimatePower(int exponent);
324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// and denominator.
344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void InitialScaledStartValues(double v,
354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     int estimated_power,
364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     bool need_boundary_deltas,
374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* numerator,
384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* denominator,
394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* delta_minus,
404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* delta_plus);
414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Multiplies numerator/denominator so that its values lies in the range 1-10.
424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Returns decimal_point s.t.
434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  v = numerator'/denominator' * 10^(decimal_point-1)
444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//     where numerator' and denominator' are the values of numerator and
454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//     denominator after the call to this function.
464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void FixupMultiply10(int estimated_power, bool is_even,
474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            int* decimal_point,
484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            Bignum* numerator, Bignum* denominator,
494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            Bignum* delta_minus, Bignum* delta_plus);
504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Generates digits from the left to the right and stops when the generated
514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// digits yield the shortest decimal representation of v.
524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                   Bignum* delta_minus, Bignum* delta_plus,
544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                   bool is_even,
554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                   Vector<char> buffer, int* length);
564a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Generates 'requested_digits' after the decimal point.
574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void BignumToFixed(int requested_digits, int* decimal_point,
584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                          Bignum* numerator, Bignum* denominator,
594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                          Vector<char>(buffer), int* length);
604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Generates 'count' digits of numerator/denominator.
614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Once 'count' digits have been produced rounds the result depending on the
624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// remainder (remainders of exactly .5 round upwards). Might update the
634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// decimal_point when rounding up (for example for 0.9999).
644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void GenerateCountedDigits(int count, int* decimal_point,
654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                  Bignum* numerator, Bignum* denominator,
664a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                  Vector<char>(buffer), int* length);
674a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                Vector<char> buffer, int* length, int* decimal_point) {
71e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(v > 0);
72e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!Double(v).IsSpecial());
734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  uint64_t significand = Double(v).Significand();
744a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  bool is_even = (significand & 1) == 0;
754a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  int exponent = Double(v).Exponent();
764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  int normalized_exponent = NormalizedExponent(significand, exponent);
774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // estimated_power might be too low by 1.
784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  int estimated_power = EstimatePower(normalized_exponent);
794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Shortcut for Fixed.
814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // The requested digits correspond to the digits after the point. If the
824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // number is much too small, then there is no need in trying to get any
834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // digits.
844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    buffer[0] = '\0';
864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    *length = 0;
874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Set decimal-point to -requested_digits. This is what Gay does.
884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Note that it should not have any effect anyways since the string is
894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // empty.
904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    *decimal_point = -requested_digits;
914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    return;
924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Bignum numerator;
954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Bignum denominator;
964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Bignum delta_minus;
974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Bignum delta_plus;
984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Make sure the bignum can grow large enough. The smallest double equals
994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
1004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // The maximum double is 1.7976931348623157e308 which needs fewer than
1014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // 308*4 binary digits.
102e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Bignum::kMaxSignificantBits >= 324*4);
1034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST);
1044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  InitialScaledStartValues(v, estimated_power, need_boundary_deltas,
1054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                           &numerator, &denominator,
1064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                           &delta_minus, &delta_plus);
1074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // We now have v = (numerator / denominator) * 10^estimated_power.
1084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  FixupMultiply10(estimated_power, is_even, decimal_point,
1094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                  &numerator, &denominator,
1104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                  &delta_minus, &delta_plus);
1114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
1124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //  1 <= (numerator + delta_plus) / denominator < 10
1134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  switch (mode) {
1144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    case BIGNUM_DTOA_SHORTEST:
1154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      GenerateShortestDigits(&numerator, &denominator,
1164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                             &delta_minus, &delta_plus,
1174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                             is_even, buffer, length);
1184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      break;
1194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    case BIGNUM_DTOA_FIXED:
1204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      BignumToFixed(requested_digits, decimal_point,
1214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                    &numerator, &denominator,
1224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                    buffer, length);
1234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      break;
1244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    case BIGNUM_DTOA_PRECISION:
1254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      GenerateCountedDigits(requested_digits, decimal_point,
1264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            &numerator, &denominator,
1274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            buffer, length);
1284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      break;
1294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    default:
1304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      UNREACHABLE();
1314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
1324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  buffer[*length] = '\0';
1334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
1344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// The procedure starts generating digits from the left to the right and stops
1374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// when the generated digits yield the shortest decimal representation of v. A
1384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// decimal representation of v is a number lying closer to v than to any other
1394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// double, so it converts to v when read.
1404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
1414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// This is true if d, the decimal representation, is between m- and m+, the
1424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// upper and lower boundaries. d must be strictly between them if !is_even.
1434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//           m- := (numerator - delta_minus) / denominator
1444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//           m+ := (numerator + delta_plus) / denominator
1454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
1464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
1474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//   If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
1484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//   will be produced. This should be the standard precondition.
1494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
1504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                   Bignum* delta_minus, Bignum* delta_plus,
1514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                   bool is_even,
1524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                   Vector<char> buffer, int* length) {
1534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Small optimization: if delta_minus and delta_plus are the same just reuse
1544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // one of the two bignums.
1554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (Bignum::Equal(*delta_minus, *delta_plus)) {
1564a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_plus = delta_minus;
1574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
1584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  *length = 0;
1594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  while (true) {
1604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    uint16_t digit;
1614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    digit = numerator->DivideModuloIntBignum(*denominator);
162e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(digit <= 9);  // digit is a uint16_t and therefore always positive.
1634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // digit = numerator / denominator (integer division).
1644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // numerator = numerator % denominator.
1654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    buffer[(*length)++] = digit + '0';
1664a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1674a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Can we stop already?
1684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // If the remainder of the division is less than the distance to the lower
1694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // boundary we can stop. In this case we simply round down (discarding the
1704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // remainder).
1714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Similarly we test if we can round up (using the upper boundary).
1724a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    bool in_delta_room_minus;
1734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    bool in_delta_room_plus;
1744a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if (is_even) {
1754a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
1764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else {
1774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
1784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
1794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if (is_even) {
1804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      in_delta_room_plus =
1814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com          Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
1824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else {
1834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      in_delta_room_plus =
1844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com          Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
1854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
1864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if (!in_delta_room_minus && !in_delta_room_plus) {
1874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Prepare for next iteration.
1884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      numerator->Times10();
1894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_minus->Times10();
1904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // We optimized delta_plus to be equal to delta_minus (if they share the
1914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // same value). So don't multiply delta_plus if they point to the same
1924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // object.
1934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      if (delta_minus != delta_plus) {
1944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        delta_plus->Times10();
1954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      }
1964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else if (in_delta_room_minus && in_delta_room_plus) {
1974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Let's see if 2*numerator < denominator.
1984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // If yes, then the next digit would be < 5 and we can round down.
1994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
2004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      if (compare < 0) {
2014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // Remaining digits are less than .5. -> Round down (== do nothing).
2024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      } else if (compare > 0) {
2034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // Remaining digits are more than .5 of denominator. -> Round up.
2044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // Note that the last digit could not be a '9' as otherwise the whole
2054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // loop would have stopped earlier.
2064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // We still have an assert here in case the preconditions were not
2074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // satisfied.
208e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(buffer[(*length) - 1] != '9');
2094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        buffer[(*length) - 1]++;
2104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      } else {
2114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // Halfway case.
2124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // TODO(floitsch): need a way to solve half-way cases.
2134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        //   For now let's round towards even (since this is what Gay seems to
2144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        //   do).
2154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
2164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        if ((buffer[(*length) - 1] - '0') % 2 == 0) {
2174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com          // Round down => Do nothing.
2184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        } else {
219e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(buffer[(*length) - 1] != '9');
2204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com          buffer[(*length) - 1]++;
2214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        }
2224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      }
2234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      return;
2244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else if (in_delta_room_minus) {
2254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Round down (== do nothing).
2264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      return;
2274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else {  // in_delta_room_plus
2284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Round up.
2294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Note again that the last digit could not be '9' since this would have
2304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // stopped the loop earlier.
231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      // We still have an DCHECK here, in case the preconditions were not
2324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // satisfied.
233e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(buffer[(*length) -1] != '9');
2344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      buffer[(*length) - 1]++;
2354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      return;
2364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
2374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
2384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
2394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
2404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
2414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Let v = numerator / denominator < 10.
2424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
2434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// from left to right. Once 'count' digits have been produced we decide wether
2444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// to round up or down. Remainders of exactly .5 round upwards. Numbers such
2454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// as 9.999999 propagate a carry all the way, and change the
2464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// exponent (decimal_point), when rounding upwards.
2474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void GenerateCountedDigits(int count, int* decimal_point,
2484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                  Bignum* numerator, Bignum* denominator,
2494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                  Vector<char>(buffer), int* length) {
250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(count >= 0);
2514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  for (int i = 0; i < count - 1; ++i) {
2524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    uint16_t digit;
2534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    digit = numerator->DivideModuloIntBignum(*denominator);
254e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(digit <= 9);  // digit is a uint16_t and therefore always positive.
2554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // digit = numerator / denominator (integer division).
2564a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // numerator = numerator % denominator.
2574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    buffer[i] = digit + '0';
2584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Prepare for next iteration.
2594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    numerator->Times10();
2604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
2614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Generate the last digit.
2624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  uint16_t digit;
2634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  digit = numerator->DivideModuloIntBignum(*denominator);
2644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
2654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    digit++;
2664a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
2674a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  buffer[count - 1] = digit + '0';
2684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Correct bad digits (in case we had a sequence of '9's). Propagate the
2694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // carry until we hat a non-'9' or til we reach the first digit.
2704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  for (int i = count - 1; i > 0; --i) {
2714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if (buffer[i] != '0' + 10) break;
2724a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    buffer[i] = '0';
2734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    buffer[i - 1]++;
2744a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
2754a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (buffer[0] == '0' + 10) {
2764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Propagate a carry past the top place.
2774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    buffer[0] = '1';
2784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    (*decimal_point)++;
2794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
2804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  *length = count;
2814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
2824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
2834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
2844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Generates 'requested_digits' after the decimal point. It might omit
2854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// trailing '0's. If the input number is too small then no digits at all are
2864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// generated (ex.: 2 fixed digits for 0.00001).
2874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
2884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Input verifies:  1 <= (numerator + delta) / denominator < 10.
2894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void BignumToFixed(int requested_digits, int* decimal_point,
2904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                          Bignum* numerator, Bignum* denominator,
2914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                          Vector<char>(buffer), int* length) {
2924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Note that we have to look at more than just the requested_digits, since
2934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // a number could be rounded up. Example: v=0.5 with requested_digits=0.
2944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Even though the power of v equals 0 we can't just stop here.
2954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (-(*decimal_point) > requested_digits) {
2964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // The number is definitively too small.
2974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Ex: 0.001 with requested_digits == 1.
2984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Set decimal-point to -requested_digits. This is what Gay does.
2994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Note that it should not have any effect anyways since the string is
3004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // empty.
3014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    *decimal_point = -requested_digits;
3024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    *length = 0;
3034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    return;
3044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  } else if (-(*decimal_point) == requested_digits) {
3054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // We only need to verify if the number rounds down or up.
3064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Ex: 0.04 and 0.06 with requested_digits == 1.
307e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(*decimal_point == -requested_digits);
3084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Initially the fraction lies in range (1, 10]. Multiply the denominator
3094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // by 10 so that we can compare more easily.
3104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    denominator->Times10();
3114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
3124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // If the fraction is >= 0.5 then we have to include the rounded
3134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // digit.
3144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      buffer[0] = '1';
3154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      *length = 1;
3164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      (*decimal_point)++;
3174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else {
3184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Note that we caught most of similar cases earlier.
3194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      *length = 0;
3204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
3214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    return;
3224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  } else {
3234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // The requested digits correspond to the digits after the point.
3244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // The variable 'needed_digits' includes the digits before the point.
3254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    int needed_digits = (*decimal_point) + requested_digits;
3264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    GenerateCountedDigits(needed_digits, decimal_point,
3274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                          numerator, denominator,
3284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                          buffer, length);
3294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
3304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
3314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Returns an estimation of k such that 10^(k-1) <= v < 10^k where
3344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// v = f * 2^exponent and 2^52 <= f < 2^53.
3354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// v is hence a normalized double with the given exponent. The output is an
3364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// approximation for the exponent of the decimal approimation .digits * 10^k.
3374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
3384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
3394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Note: this property holds for v's upper boundary m+ too.
3404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    10^k <= m+ < 10^k+1.
3414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//   (see explanation below).
3424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
3434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Examples:
3444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  EstimatePower(0)   => 16
3454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  EstimatePower(-52) => 0
3464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
3474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
3484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic int EstimatePower(int exponent) {
3494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // This function estimates log10 of v where v = f*2^e (with e == exponent).
3504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
3514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Note that f is bounded by its container size. Let p = 53 (the double's
3524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // significand size). Then 2^(p-1) <= f < 2^p.
3534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //
3544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
3554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
3564a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // The computed number undershoots by less than 0.631 (when we compute log3
3574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // and not log10).
3584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //
3594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Optimization: since we only need an approximated result this computation
3604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
3614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // not really measurable, though.
3624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //
3634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Since we want to avoid overshooting we decrement by 1e10 so that
3644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // floating-point imprecisions don't affect us.
3654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //
3664a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Explanation for v's boundary m+: the computation takes advantage of
3674a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
3684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // (even for denormals where the delta can be much more important).
3694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  const double k1Log10 = 0.30102999566398114;  // 1/lg(10)
3714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3724a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // For doubles len(f) == 53 (don't forget the hidden bit).
3734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  const int kSignificandSize = 53;
374e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  double estimate =
375e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      std::ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
3764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return static_cast<int>(estimate);
3774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
3784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// See comments for InitialScaledStartValues.
3814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void InitialScaledStartValuesPositiveExponent(
3824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    double v, int estimated_power, bool need_boundary_deltas,
3834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    Bignum* numerator, Bignum* denominator,
3844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    Bignum* delta_minus, Bignum* delta_plus) {
3854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // A positive exponent implies a positive power.
386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(estimated_power >= 0);
3874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Since the estimated_power is positive we simply multiply the denominator
3884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // by 10^estimated_power.
3894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // numerator = v.
3914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  numerator->AssignUInt64(Double(v).Significand());
3924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  numerator->ShiftLeft(Double(v).Exponent());
3934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // denominator = 10^estimated_power.
3944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  denominator->AssignPowerUInt16(10, estimated_power);
3954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
3964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (need_boundary_deltas) {
3974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Introduce a common denominator so that the deltas to the boundaries are
3984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // integers.
3994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    denominator->ShiftLeft(1);
4004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    numerator->ShiftLeft(1);
4014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
4024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // denominator (of 2) delta_plus equals 2^e.
4034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_plus->AssignUInt16(1);
4044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_plus->ShiftLeft(Double(v).Exponent());
4054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Same for delta_minus (with adjustments below if f == 2^p-1).
4064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_minus->AssignUInt16(1);
4074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_minus->ShiftLeft(Double(v).Exponent());
4084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // If the significand (without the hidden bit) is 0, then the lower
4104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // boundary is closer than just half a ulp (unit in the last place).
4114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // There is only one exception: if the next lower number is a denormal then
4124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // the distance is 1 ulp. This cannot be the case for exponent >= 0 (but we
4134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // have to test it in the other function where exponent < 0).
4144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    uint64_t v_bits = Double(v).AsUint64();
4154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if ((v_bits & Double::kSignificandMask) == 0) {
4164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // The lower boundary is closer at half the distance of "normal" numbers.
4174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Increase the common denominator and adapt all but the delta_minus.
4184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      denominator->ShiftLeft(1);  // *2
4194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      numerator->ShiftLeft(1);    // *2
4204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_plus->ShiftLeft(1);   // *2
4214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
4224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
4234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
4244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// See comments for InitialScaledStartValues
4274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void InitialScaledStartValuesNegativeExponentPositivePower(
4284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    double v, int estimated_power, bool need_boundary_deltas,
4294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    Bignum* numerator, Bignum* denominator,
4304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    Bignum* delta_minus, Bignum* delta_plus) {
4314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  uint64_t significand = Double(v).Significand();
4324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  int exponent = Double(v).Exponent();
4334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // v = f * 2^e with e < 0, and with estimated_power >= 0.
4344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // This means that e is close to 0 (have a look at how estimated_power is
4354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // computed).
4364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // numerator = significand
4384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //  since v = significand * 2^exponent this is equivalent to
4394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //  numerator = v * / 2^-exponent
4404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  numerator->AssignUInt64(significand);
4414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
4424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  denominator->AssignPowerUInt16(10, estimated_power);
4434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  denominator->ShiftLeft(-exponent);
4444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (need_boundary_deltas) {
4464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Introduce a common denominator so that the deltas to the boundaries are
4474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // integers.
4484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    denominator->ShiftLeft(1);
4494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    numerator->ShiftLeft(1);
4504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
4514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // denominator (of 2) delta_plus equals 2^e.
4524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Given that the denominator already includes v's exponent the distance
4534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // to the boundaries is simply 1.
4544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_plus->AssignUInt16(1);
4554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Same for delta_minus (with adjustments below if f == 2^p-1).
4564a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_minus->AssignUInt16(1);
4574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // If the significand (without the hidden bit) is 0, then the lower
4594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // boundary is closer than just one ulp (unit in the last place).
4604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // There is only one exception: if the next lower number is a denormal
4614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // then the distance is 1 ulp. Since the exponent is close to zero
4624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // (otherwise estimated_power would have been negative) this cannot happen
4634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // here either.
4644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    uint64_t v_bits = Double(v).AsUint64();
4654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if ((v_bits & Double::kSignificandMask) == 0) {
4664a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // The lower boundary is closer at half the distance of "normal" numbers.
4674a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      // Increase the denominator and adapt all but the delta_minus.
4684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      denominator->ShiftLeft(1);  // *2
4694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      numerator->ShiftLeft(1);    // *2
4704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_plus->ShiftLeft(1);   // *2
4714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
4724a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
4734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
4744a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4754a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// See comments for InitialScaledStartValues
4774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void InitialScaledStartValuesNegativeExponentNegativePower(
4784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    double v, int estimated_power, bool need_boundary_deltas,
4794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    Bignum* numerator, Bignum* denominator,
4804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    Bignum* delta_minus, Bignum* delta_plus) {
4814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  const uint64_t kMinimalNormalizedExponent =
4824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      V8_2PART_UINT64_C(0x00100000, 00000000);
4834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  uint64_t significand = Double(v).Significand();
4844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  int exponent = Double(v).Exponent();
4854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Instead of multiplying the denominator with 10^estimated_power we
4864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // multiply all values (numerator and deltas) by 10^-estimated_power.
4874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Use numerator as temporary container for power_ten.
4894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Bignum* power_ten = numerator;
4904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  power_ten->AssignPowerUInt16(10, -estimated_power);
4914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (need_boundary_deltas) {
4934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Since power_ten == numerator we must make a copy of 10^estimated_power
4944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // before we complete the computation of the numerator.
4954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // delta_plus = delta_minus = 10^estimated_power
4964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_plus->AssignBignum(*power_ten);
4974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    delta_minus->AssignBignum(*power_ten);
4984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
4994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // numerator = significand * 2 * 10^-estimated_power
5014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //  since v = significand * 2^exponent this is equivalent to
5024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
5034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Remember: numerator has been abused as power_ten. So no need to assign it
5044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //  to itself.
505e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(numerator == power_ten);
5064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  numerator->MultiplyByUInt64(significand);
5074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // denominator = 2 * 2^-exponent with exponent < 0.
5094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  denominator->AssignUInt16(1);
5104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  denominator->ShiftLeft(-exponent);
5114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (need_boundary_deltas) {
5134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Introduce a common denominator so that the deltas to the boundaries are
5144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // integers.
5154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    numerator->ShiftLeft(1);
5164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    denominator->ShiftLeft(1);
5174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // With this shift the boundaries have their correct value, since
5184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // delta_plus = 10^-estimated_power, and
5194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // delta_minus = 10^-estimated_power.
5204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // These assignments have been done earlier.
5214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // The special case where the lower boundary is twice as close.
5234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // This time we have to look out for the exception too.
5244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    uint64_t v_bits = Double(v).AsUint64();
5254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if ((v_bits & Double::kSignificandMask) == 0 &&
5264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // The only exception where a significand == 0 has its boundaries at
5274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        // "normal" distances:
5284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent) {
5294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      numerator->ShiftLeft(1);    // *2
5304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      denominator->ShiftLeft(1);  // *2
5314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_plus->ShiftLeft(1);   // *2
5324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
5334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
5344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
5354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Let v = significand * 2^exponent.
5384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
5394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// and denominator. The functions GenerateShortestDigits and
5404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// GenerateCountedDigits will then convert this ratio to its decimal
5414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// representation d, with the required accuracy.
5424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Then d * 10^estimated_power is the representation of v.
5434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// (Note: the fraction and the estimated_power might get adjusted before
5444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// generating the decimal representation.)
5454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
5464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// The initial start values consist of:
5474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
5484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  - a scaled (common) denominator.
5494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  optionally (used by GenerateShortestDigits to decide if it has the shortest
5504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  decimal converting back to v):
5514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  - v - m-: the distance to the lower boundary.
5524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  - m+ - v: the distance to the upper boundary.
5534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
5544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
5554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
5564a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Let ep == estimated_power, then the returned values will satisfy:
5574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  v / 10^ep = numerator / denominator.
5584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  v's boundarys m- and m+:
5594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    m- / 10^ep == v / 10^ep - delta_minus / denominator
5604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    m+ / 10^ep == v / 10^ep + delta_plus / denominator
5614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  Or in other words:
5624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    m- == v - delta_minus * 10^ep / denominator;
5634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    m+ == v + delta_plus * 10^ep / denominator;
5644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
5654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Since 10^(k-1) <= v < 10^k    (with k == estimated_power)
5664a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  or       10^k <= v < 10^(k+1)
5674a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  we then have 0.1 <= numerator/denominator < 1
5684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//           or    1 <= numerator/denominator < 10
5694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
5704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// It is then easy to kickstart the digit-generation routine.
5714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//
5724a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// The boundary-deltas are only filled if need_boundary_deltas is set.
5734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void InitialScaledStartValues(double v,
5744a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     int estimated_power,
5754a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     bool need_boundary_deltas,
5764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* numerator,
5774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* denominator,
5784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* delta_minus,
5794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                                     Bignum* delta_plus) {
5804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (Double(v).Exponent() >= 0) {
5814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    InitialScaledStartValuesPositiveExponent(
5824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        v, estimated_power, need_boundary_deltas,
5834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        numerator, denominator, delta_minus, delta_plus);
5844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  } else if (estimated_power >= 0) {
5854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    InitialScaledStartValuesNegativeExponentPositivePower(
5864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        v, estimated_power, need_boundary_deltas,
5874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        numerator, denominator, delta_minus, delta_plus);
5884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  } else {
5894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    InitialScaledStartValuesNegativeExponentNegativePower(
5904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        v, estimated_power, need_boundary_deltas,
5914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com        numerator, denominator, delta_minus, delta_plus);
5924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
5934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
5944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// This routine multiplies numerator/denominator so that its values lies in the
5974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// range 1-10. That is after a call to this function we have:
5984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    1 <= (numerator + delta_plus) /denominator < 10.
5994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Let numerator the input before modification and numerator' the argument
6004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// after modification, then the output-parameter decimal_point is such that
6014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//  numerator / denominator * 10^estimated_power ==
6024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com//    numerator' / denominator' * 10^(decimal_point - 1)
6034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// In some cases estimated_power was too low, and this is already the case. We
6044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
6054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// estimated_power) but do not touch the numerator or denominator.
6064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Otherwise the routine multiplies the numerator and the deltas by 10.
6074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comstatic void FixupMultiply10(int estimated_power, bool is_even,
6084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            int* decimal_point,
6094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            Bignum* numerator, Bignum* denominator,
6104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com                            Bignum* delta_minus, Bignum* delta_plus) {
6114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  bool in_range;
6124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (is_even) {
6134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
6144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // are rounded to the closest floating-point number with even significand.
6154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
6164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  } else {
6174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
6184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
6194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (in_range) {
6204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Since numerator + delta_plus >= denominator we already have
6214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // 1 <= numerator/denominator < 10. Simply update the estimated_power.
6224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    *decimal_point = estimated_power + 1;
6234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  } else {
6244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    *decimal_point = estimated_power;
6254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    numerator->Times10();
6264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    if (Bignum::Equal(*delta_minus, *delta_plus)) {
6274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_minus->Times10();
6284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_plus->AssignBignum(*delta_minus);
6294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    } else {
6304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_minus->Times10();
6314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      delta_plus->Times10();
6324a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    }
6334a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
6344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
6354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
6364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} }  // namespace v8::internal
637