Diff from to

# File double-conversion/src/bignum-dtoa.cc

#include "bignum-dtoa.h"

#include "bignum.h"
-#include "double.h"
+#include "ieee.h"

namespace double_conversion {

static int EstimatePower(int exponent);
// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
// and denominator.
-static void InitialScaledStartValues(double v,
+static void InitialScaledStartValues(uint64_t significand,
+                                     int exponent,
+                                     bool lower_boundary_is_closer,
int estimated_power,
bool need_boundary_deltas,
Bignum* numerator,
Vector<char> buffer, int* length, int* decimal_point) {
ASSERT(v > 0);
ASSERT(!Double(v).IsSpecial());
-  uint64_t significand = Double(v).Significand();
+  uint64_t significand;
+  int exponent;
+  bool lower_boundary_is_closer;
+  if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) {
+    float f = static_cast<float>(v);
+    ASSERT(f == v);
+    significand = Single(f).Significand();
+    exponent = Single(f).Exponent();
+    lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
+  } else {
+    significand = Double(v).Significand();
+    exponent = Double(v).Exponent();
+    lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser();
+  }
+  bool need_boundary_deltas =
+      (mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE);
+
bool is_even = (significand & 1) == 0;
-  int exponent = Double(v).Exponent();
int normalized_exponent = NormalizedExponent(significand, exponent);
// estimated_power might be too low by 1.
int estimated_power = EstimatePower(normalized_exponent);
// The maximum double is 1.7976931348623157e308 which needs fewer than
// 308*4 binary digits.
ASSERT(Bignum::kMaxSignificantBits >= 324*4);
-  bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST);
-  InitialScaledStartValues(v, estimated_power, need_boundary_deltas,
+  InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
+                           estimated_power, need_boundary_deltas,
&numerator, &denominator,
&delta_minus, &delta_plus);
// We now have v = (numerator / denominator) * 10^estimated_power.
//  1 <= (numerator + delta_plus) / denominator < 10
switch (mode) {
case BIGNUM_DTOA_SHORTEST:
+    case BIGNUM_DTOA_SHORTEST_SINGLE:
GenerateShortestDigits(&numerator, &denominator,
&delta_minus, &delta_plus,
is_even, buffer, length);
const double k1Log10 = 0.30102999566398114;  // 1/lg(10)

// For doubles len(f) == 53 (don't forget the hidden bit).
-  const int kSignificandSize = 53;
+  const int kSignificandSize = Double::kSignificandSize;
double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
return static_cast<int>(estimate);
}

static void InitialScaledStartValuesPositiveExponent(
-    double v, int estimated_power, bool need_boundary_deltas,
+    uint64_t significand, int exponent,
+    int estimated_power, bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
// A positive exponent implies a positive power.
// by 10^estimated_power.

// numerator = v.
-  numerator->AssignUInt64(Double(v).Significand());
-  numerator->ShiftLeft(Double(v).Exponent());
+  numerator->AssignUInt64(significand);
+  numerator->ShiftLeft(exponent);
// denominator = 10^estimated_power.
denominator->AssignPowerUInt16(10, estimated_power);

// Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
// denominator (of 2) delta_plus equals 2^e.
delta_plus->AssignUInt16(1);
-    delta_plus->ShiftLeft(Double(v).Exponent());
-    // Same for delta_minus (with adjustments below if f == 2^p-1).
+    delta_plus->ShiftLeft(exponent);
+    // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
delta_minus->AssignUInt16(1);
-    delta_minus->ShiftLeft(Double(v).Exponent());
-
-    // If the significand (without the hidden bit) is 0, then the lower
-    // boundary is closer than just half a ulp (unit in the last place).
-    // There is only one exception: if the next lower number is a denormal then
-    // the distance is 1 ulp. This cannot be the case for exponent >= 0 (but we
-    // have to test it in the other function where exponent < 0).
-    uint64_t v_bits = Double(v).AsUint64();
-    if ((v_bits & Double::kSignificandMask) == 0) {
-      // The lower boundary is closer at half the distance of "normal" numbers.
-      // Increase the common denominator and adapt all but the delta_minus.
-      denominator->ShiftLeft(1);  // *2
-      numerator->ShiftLeft(1);    // *2
-      delta_plus->ShiftLeft(1);   // *2
-    }
+    delta_minus->ShiftLeft(exponent);
}
}

static void InitialScaledStartValuesNegativeExponentPositivePower(
-    double v, int estimated_power, bool need_boundary_deltas,
+    uint64_t significand, int exponent,
+    int estimated_power, bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
-  uint64_t significand = Double(v).Significand();
-  int exponent = Double(v).Exponent();
// v = f * 2^e with e < 0, and with estimated_power >= 0.
// This means that e is close to 0 (have a look at how estimated_power is
// computed).
// Given that the denominator already includes v's exponent the distance
// to the boundaries is simply 1.
delta_plus->AssignUInt16(1);
-    // Same for delta_minus (with adjustments below if f == 2^p-1).
+    // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
delta_minus->AssignUInt16(1);
-
-    // If the significand (without the hidden bit) is 0, then the lower
-    // boundary is closer than just one ulp (unit in the last place).
-    // There is only one exception: if the next lower number is a denormal
-    // then the distance is 1 ulp. Since the exponent is close to zero
-    // (otherwise estimated_power would have been negative) this cannot happen
-    // here either.
-    uint64_t v_bits = Double(v).AsUint64();
-    if ((v_bits & Double::kSignificandMask) == 0) {
-      // The lower boundary is closer at half the distance of "normal" numbers.
-      // Increase the denominator and adapt all but the delta_minus.
-      denominator->ShiftLeft(1);  // *2
-      numerator->ShiftLeft(1);    // *2
-      delta_plus->ShiftLeft(1);   // *2
-    }
}
}

static void InitialScaledStartValuesNegativeExponentNegativePower(
-    double v, int estimated_power, bool need_boundary_deltas,
+    uint64_t significand, int exponent,
+    int estimated_power, bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
-  const uint64_t kMinimalNormalizedExponent =
-      UINT64_2PART_C(0x00100000, 00000000);
-  uint64_t significand = Double(v).Significand();
-  int exponent = Double(v).Exponent();
// Instead of multiplying the denominator with 10^estimated_power we
// multiply all values (numerator and deltas) by 10^-estimated_power.

// delta_plus = 10^-estimated_power, and
// delta_minus = 10^-estimated_power.
// These assignments have been done earlier.
-
-    // The special case where the lower boundary is twice as close.
-    // This time we have to look out for the exception too.
-    uint64_t v_bits = Double(v).AsUint64();
-    if ((v_bits & Double::kSignificandMask) == 0 &&
-        // The only exception where a significand == 0 has its boundaries at
-        // "normal" distances:
-        (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent) {
-      numerator->ShiftLeft(1);    // *2
-      denominator->ShiftLeft(1);  // *2
-      delta_plus->ShiftLeft(1);   // *2
-    }
+    // The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
}
}

//
// It is then easy to kickstart the digit-generation routine.
//
-// The boundary-deltas are only filled if need_boundary_deltas is set.
-static void InitialScaledStartValues(double v,
+// The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST
+// or BIGNUM_DTOA_SHORTEST_SINGLE.
+
+static void InitialScaledStartValues(uint64_t significand,
+                                     int exponent,
+                                     bool lower_boundary_is_closer,
int estimated_power,
bool need_boundary_deltas,
Bignum* numerator,
Bignum* denominator,
Bignum* delta_minus,
Bignum* delta_plus) {
-  if (Double(v).Exponent() >= 0) {
+  if (exponent >= 0) {
InitialScaledStartValuesPositiveExponent(
-        v, estimated_power, need_boundary_deltas,
+        significand, exponent, estimated_power, need_boundary_deltas,
numerator, denominator, delta_minus, delta_plus);
} else if (estimated_power >= 0) {
InitialScaledStartValuesNegativeExponentPositivePower(
-        v, estimated_power, need_boundary_deltas,
+        significand, exponent, estimated_power, need_boundary_deltas,
numerator, denominator, delta_minus, delta_plus);
} else {
InitialScaledStartValuesNegativeExponentNegativePower(
-        v, estimated_power, need_boundary_deltas,
+        significand, exponent, estimated_power, need_boundary_deltas,
numerator, denominator, delta_minus, delta_plus);
}
+
+  if (need_boundary_deltas && lower_boundary_is_closer) {
+    // The lower boundary is closer at half the distance of "normal" numbers.
+    // Increase the common denominator and adapt all but the delta_minus.
+    denominator->ShiftLeft(1);  // *2
+    numerator->ShiftLeft(1);    // *2
+    delta_plus->ShiftLeft(1);   // *2
+  }
}