// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"

#include <math.h>

#include "bignum-dtoa.h"

#include "bignum.h"
#include "double.h"

namespace WTF {

namespace double_conversion {

    static int NormalizedExponent(uint64_t significand, int exponent) {
        ASSERT(significand != 0);
        while ((significand & Double::kHiddenBit) == 0) {
            significand = significand << 1;
            exponent = exponent - 1;
        }
        return exponent;
    }


    // Forward declarations:
    // Returns an estimation of k such that 10^(k-1) <= v < 10^k.
    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,
                                         int estimated_power,
                                         bool need_boundary_deltas,
                                         Bignum* numerator,
                                         Bignum* denominator,
                                         Bignum* delta_minus,
                                         Bignum* delta_plus);
    // Multiplies numerator/denominator so that its values lies in the range 1-10.
    // Returns decimal_point s.t.
    //  v = numerator'/denominator' * 10^(decimal_point-1)
    //     where numerator' and denominator' are the values of numerator and
    //     denominator after the call to this function.
    static void FixupMultiply10(int estimated_power, bool is_even,
                                int* decimal_point,
                                Bignum* numerator, Bignum* denominator,
                                Bignum* delta_minus, Bignum* delta_plus);
    // Generates digits from the left to the right and stops when the generated
    // digits yield the shortest decimal representation of v.
    static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
                                       Bignum* delta_minus, Bignum* delta_plus,
                                       bool is_even,
                                       Vector<char> buffer, int* length);
    // Generates 'requested_digits' after the decimal point.
    static void BignumToFixed(int requested_digits, int* decimal_point,
                              Bignum* numerator, Bignum* denominator,
                              Vector<char>(buffer), int* length);
    // Generates 'count' digits of numerator/denominator.
    // Once 'count' digits have been produced rounds the result depending on the
    // remainder (remainders of exactly .5 round upwards). Might update the
    // decimal_point when rounding up (for example for 0.9999).
    static void GenerateCountedDigits(int count, int* decimal_point,
                                      Bignum* numerator, Bignum* denominator,
                                      Vector<char>(buffer), int* length);


    void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
                    Vector<char> buffer, int* length, int* decimal_point) {
        ASSERT(v > 0);
        ASSERT(!Double(v).IsSpecial());
        uint64_t significand = Double(v).Significand();
        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);

        // Shortcut for Fixed.
        // The requested digits correspond to the digits after the point. If the
        // number is much too small, then there is no need in trying to get any
        // digits.
        if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
            buffer[0] = '\0';
            *length = 0;
            // Set decimal-point to -requested_digits. This is what Gay does.
            // Note that it should not have any effect anyways since the string is
            // empty.
            *decimal_point = -requested_digits;
            return;
        }

        Bignum numerator;
        Bignum denominator;
        Bignum delta_minus;
        Bignum delta_plus;
        // Make sure the bignum can grow large enough. The smallest double equals
        // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
        // 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,
                                 &numerator, &denominator,
                                 &delta_minus, &delta_plus);
        // We now have v = (numerator / denominator) * 10^estimated_power.
        FixupMultiply10(estimated_power, is_even, decimal_point,
                        &numerator, &denominator,
                        &delta_minus, &delta_plus);
        // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
        //  1 <= (numerator + delta_plus) / denominator < 10
        switch (mode) {
            case BIGNUM_DTOA_SHORTEST:
                GenerateShortestDigits(&numerator, &denominator,
                                       &delta_minus, &delta_plus,
                                       is_even, buffer, length);
                break;
            case BIGNUM_DTOA_FIXED:
                BignumToFixed(requested_digits, decimal_point,
                              &numerator, &denominator,
                              buffer, length);
                break;
            case BIGNUM_DTOA_PRECISION:
                GenerateCountedDigits(requested_digits, decimal_point,
                                      &numerator, &denominator,
                                      buffer, length);
                break;
            default:
                UNREACHABLE();
        }
        buffer[*length] = '\0';
    }


    // The procedure starts generating digits from the left to the right and stops
    // when the generated digits yield the shortest decimal representation of v. A
    // decimal representation of v is a number lying closer to v than to any other
    // double, so it converts to v when read.
    //
    // This is true if d, the decimal representation, is between m- and m+, the
    // upper and lower boundaries. d must be strictly between them if !is_even.
    //           m- := (numerator - delta_minus) / denominator
    //           m+ := (numerator + delta_plus) / denominator
    //
    // Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
    //   If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
    //   will be produced. This should be the standard precondition.
    static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
                                       Bignum* delta_minus, Bignum* delta_plus,
                                       bool is_even,
                                       Vector<char> buffer, int* length) {
        // Small optimization: if delta_minus and delta_plus are the same just reuse
        // one of the two bignums.
        if (Bignum::Equal(*delta_minus, *delta_plus)) {
            delta_plus = delta_minus;
        }
        *length = 0;
        while (true) {
            uint16_t digit;
            digit = numerator->DivideModuloIntBignum(*denominator);
            ASSERT(digit <= 9);  // digit is a uint16_t and therefore always positive.
            // digit = numerator / denominator (integer division).
            // numerator = numerator % denominator.
            buffer[(*length)++] = digit + '0';

            // Can we stop already?
            // If the remainder of the division is less than the distance to the lower
            // boundary we can stop. In this case we simply round down (discarding the
            // remainder).
            // Similarly we test if we can round up (using the upper boundary).
            bool in_delta_room_minus;
            bool in_delta_room_plus;
            if (is_even) {
                in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
            } else {
                in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
            }
            if (is_even) {
                in_delta_room_plus =
                Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
            } else {
                in_delta_room_plus =
                Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
            }
            if (!in_delta_room_minus && !in_delta_room_plus) {
                // Prepare for next iteration.
                numerator->Times10();
                delta_minus->Times10();
                // We optimized delta_plus to be equal to delta_minus (if they share the
                // same value). So don't multiply delta_plus if they point to the same
                // object.
                if (delta_minus != delta_plus) {
                    delta_plus->Times10();
                }
            } else if (in_delta_room_minus && in_delta_room_plus) {
                // Let's see if 2*numerator < denominator.
                // If yes, then the next digit would be < 5 and we can round down.
                int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
                if (compare < 0) {
                    // Remaining digits are less than .5. -> Round down (== do nothing).
                } else if (compare > 0) {
                    // Remaining digits are more than .5 of denominator. -> Round up.
                    // Note that the last digit could not be a '9' as otherwise the whole
                    // loop would have stopped earlier.
                    // We still have an assert here in case the preconditions were not
                    // satisfied.
                    ASSERT(buffer[(*length) - 1] != '9');
                    buffer[(*length) - 1]++;
                } else {
                    // Halfway case.
                    // TODO(floitsch): need a way to solve half-way cases.
                    //   For now let's round towards even (since this is what Gay seems to
                    //   do).

                    if ((buffer[(*length) - 1] - '0') % 2 == 0) {
                        // Round down => Do nothing.
                    } else {
                        ASSERT(buffer[(*length) - 1] != '9');
                        buffer[(*length) - 1]++;
                    }
                }
                return;
            } else if (in_delta_room_minus) {
                // Round down (== do nothing).
                return;
            } else {  // in_delta_room_plus
                // Round up.
                // Note again that the last digit could not be '9' since this would have
                // stopped the loop earlier.
                // We still have an ASSERT here, in case the preconditions were not
                // satisfied.
                ASSERT(buffer[(*length) -1] != '9');
                buffer[(*length) - 1]++;
                return;
            }
        }
    }


    // Let v = numerator / denominator < 10.
    // Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
    // from left to right. Once 'count' digits have been produced we decide wether
    // to round up or down. Remainders of exactly .5 round upwards. Numbers such
    // as 9.999999 propagate a carry all the way, and change the
    // exponent (decimal_point), when rounding upwards.
    static void GenerateCountedDigits(int count, int* decimal_point,
                                      Bignum* numerator, Bignum* denominator,
                                      Vector<char>(buffer), int* length) {
        ASSERT(count >= 0);
        for (int i = 0; i < count - 1; ++i) {
            uint16_t digit;
            digit = numerator->DivideModuloIntBignum(*denominator);
            ASSERT(digit <= 9);  // digit is a uint16_t and therefore always positive.
            // digit = numerator / denominator (integer division).
            // numerator = numerator % denominator.
            buffer[i] = digit + '0';
            // Prepare for next iteration.
            numerator->Times10();
        }
        // Generate the last digit.
        uint16_t digit;
        digit = numerator->DivideModuloIntBignum(*denominator);
        if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
            digit++;
        }
        buffer[count - 1] = digit + '0';
        // Correct bad digits (in case we had a sequence of '9's). Propagate the
        // carry until we hat a non-'9' or til we reach the first digit.
        for (int i = count - 1; i > 0; --i) {
            if (buffer[i] != '0' + 10) break;
            buffer[i] = '0';
            buffer[i - 1]++;
        }
        if (buffer[0] == '0' + 10) {
            // Propagate a carry past the top place.
            buffer[0] = '1';
            (*decimal_point)++;
        }
        *length = count;
    }


    // Generates 'requested_digits' after the decimal point. It might omit
    // trailing '0's. If the input number is too small then no digits at all are
    // generated (ex.: 2 fixed digits for 0.00001).
    //
    // Input verifies:  1 <= (numerator + delta) / denominator < 10.
    static void BignumToFixed(int requested_digits, int* decimal_point,
                              Bignum* numerator, Bignum* denominator,
                              Vector<char>(buffer), int* length) {
        // Note that we have to look at more than just the requested_digits, since
        // a number could be rounded up. Example: v=0.5 with requested_digits=0.
        // Even though the power of v equals 0 we can't just stop here.
        if (-(*decimal_point) > requested_digits) {
            // The number is definitively too small.
            // Ex: 0.001 with requested_digits == 1.
            // Set decimal-point to -requested_digits. This is what Gay does.
            // Note that it should not have any effect anyways since the string is
            // empty.
            *decimal_point = -requested_digits;
            *length = 0;
            return;
        } else if (-(*decimal_point) == requested_digits) {
            // We only need to verify if the number rounds down or up.
            // Ex: 0.04 and 0.06 with requested_digits == 1.
            ASSERT(*decimal_point == -requested_digits);
            // Initially the fraction lies in range (1, 10]. Multiply the denominator
            // by 10 so that we can compare more easily.
            denominator->Times10();
            if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
                // If the fraction is >= 0.5 then we have to include the rounded
                // digit.
                buffer[0] = '1';
                *length = 1;
                (*decimal_point)++;
            } else {
                // Note that we caught most of similar cases earlier.
                *length = 0;
            }
            return;
        } else {
            // The requested digits correspond to the digits after the point.
            // The variable 'needed_digits' includes the digits before the point.
            int needed_digits = (*decimal_point) + requested_digits;
            GenerateCountedDigits(needed_digits, decimal_point,
                                  numerator, denominator,
                                  buffer, length);
        }
    }


    // Returns an estimation of k such that 10^(k-1) <= v < 10^k where
    // v = f * 2^exponent and 2^52 <= f < 2^53.
    // v is hence a normalized double with the given exponent. The output is an
    // approximation for the exponent of the decimal approimation .digits * 10^k.
    //
    // The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
    // Note: this property holds for v's upper boundary m+ too.
    //    10^k <= m+ < 10^k+1.
    //   (see explanation below).
    //
    // Examples:
    //  EstimatePower(0)   => 16
    //  EstimatePower(-52) => 0
    //
    // Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
    static int EstimatePower(int exponent) {
        // This function estimates log10 of v where v = f*2^e (with e == exponent).
        // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
        // Note that f is bounded by its container size. Let p = 53 (the double's
        // significand size). Then 2^(p-1) <= f < 2^p.
        //
        // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
        // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
        // The computed number undershoots by less than 0.631 (when we compute log3
        // and not log10).
        //
        // Optimization: since we only need an approximated result this computation
        // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
        // not really measurable, though.
        //
        // Since we want to avoid overshooting we decrement by 1e10 so that
        // floating-point imprecisions don't affect us.
        //
        // Explanation for v's boundary m+: the computation takes advantage of
        // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
        // (even for denormals where the delta can be much more important).

        const double k1Log10 = 0.30102999566398114;  // 1/lg(10)

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


    // See comments for InitialScaledStartValues.
    static void InitialScaledStartValuesPositiveExponent(
                                                         double v, int estimated_power, bool need_boundary_deltas,
                                                         Bignum* numerator, Bignum* denominator,
                                                         Bignum* delta_minus, Bignum* delta_plus) {
        // A positive exponent implies a positive power.
        ASSERT(estimated_power >= 0);
        // Since the estimated_power is positive we simply multiply the denominator
        // by 10^estimated_power.

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

        if (need_boundary_deltas) {
            // Introduce a common denominator so that the deltas to the boundaries are
            // integers.
            denominator->ShiftLeft(1);
            numerator->ShiftLeft(1);
            // 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_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
            }
        }
    }


    // See comments for InitialScaledStartValues
    static void InitialScaledStartValuesNegativeExponentPositivePower(
                                                                      double v, 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).

        // numerator = significand
        //  since v = significand * 2^exponent this is equivalent to
        //  numerator = v * / 2^-exponent
        numerator->AssignUInt64(significand);
        // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
        denominator->AssignPowerUInt16(10, estimated_power);
        denominator->ShiftLeft(-exponent);

        if (need_boundary_deltas) {
            // Introduce a common denominator so that the deltas to the boundaries are
            // integers.
            denominator->ShiftLeft(1);
            numerator->ShiftLeft(1);
            // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
            // denominator (of 2) delta_plus equals 2^e.
            // 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).
            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
            }
        }
    }


    // See comments for InitialScaledStartValues
    static void InitialScaledStartValuesNegativeExponentNegativePower(
                                                                      double v, 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.

        // Use numerator as temporary container for power_ten.
        Bignum* power_ten = numerator;
        power_ten->AssignPowerUInt16(10, -estimated_power);

        if (need_boundary_deltas) {
            // Since power_ten == numerator we must make a copy of 10^estimated_power
            // before we complete the computation of the numerator.
            // delta_plus = delta_minus = 10^estimated_power
            delta_plus->AssignBignum(*power_ten);
            delta_minus->AssignBignum(*power_ten);
        }

        // numerator = significand * 2 * 10^-estimated_power
        //  since v = significand * 2^exponent this is equivalent to
        // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
        // Remember: numerator has been abused as power_ten. So no need to assign it
        //  to itself.
        ASSERT(numerator == power_ten);
        numerator->MultiplyByUInt64(significand);

        // denominator = 2 * 2^-exponent with exponent < 0.
        denominator->AssignUInt16(1);
        denominator->ShiftLeft(-exponent);

        if (need_boundary_deltas) {
            // Introduce a common denominator so that the deltas to the boundaries are
            // integers.
            numerator->ShiftLeft(1);
            denominator->ShiftLeft(1);
            // With this shift the boundaries have their correct value, since
            // 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
            }
        }
    }


    // Let v = significand * 2^exponent.
    // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
    // and denominator. The functions GenerateShortestDigits and
    // GenerateCountedDigits will then convert this ratio to its decimal
    // representation d, with the required accuracy.
    // Then d * 10^estimated_power is the representation of v.
    // (Note: the fraction and the estimated_power might get adjusted before
    // generating the decimal representation.)
    //
    // The initial start values consist of:
    //  - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
    //  - a scaled (common) denominator.
    //  optionally (used by GenerateShortestDigits to decide if it has the shortest
    //  decimal converting back to v):
    //  - v - m-: the distance to the lower boundary.
    //  - m+ - v: the distance to the upper boundary.
    //
    // v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
    //
    // Let ep == estimated_power, then the returned values will satisfy:
    //  v / 10^ep = numerator / denominator.
    //  v's boundarys m- and m+:
    //    m- / 10^ep == v / 10^ep - delta_minus / denominator
    //    m+ / 10^ep == v / 10^ep + delta_plus / denominator
    //  Or in other words:
    //    m- == v - delta_minus * 10^ep / denominator;
    //    m+ == v + delta_plus * 10^ep / denominator;
    //
    // Since 10^(k-1) <= v < 10^k    (with k == estimated_power)
    //  or       10^k <= v < 10^(k+1)
    //  we then have 0.1 <= numerator/denominator < 1
    //           or    1 <= numerator/denominator < 10
    //
    // 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,
                                         int estimated_power,
                                         bool need_boundary_deltas,
                                         Bignum* numerator,
                                         Bignum* denominator,
                                         Bignum* delta_minus,
                                         Bignum* delta_plus) {
        if (Double(v).Exponent() >= 0) {
            InitialScaledStartValuesPositiveExponent(
                                                     v, estimated_power, need_boundary_deltas,
                                                     numerator, denominator, delta_minus, delta_plus);
        } else if (estimated_power >= 0) {
            InitialScaledStartValuesNegativeExponentPositivePower(
                                                                  v, estimated_power, need_boundary_deltas,
                                                                  numerator, denominator, delta_minus, delta_plus);
        } else {
            InitialScaledStartValuesNegativeExponentNegativePower(
                                                                  v, estimated_power, need_boundary_deltas,
                                                                  numerator, denominator, delta_minus, delta_plus);
        }
    }


    // This routine multiplies numerator/denominator so that its values lies in the
    // range 1-10. That is after a call to this function we have:
    //    1 <= (numerator + delta_plus) /denominator < 10.
    // Let numerator the input before modification and numerator' the argument
    // after modification, then the output-parameter decimal_point is such that
    //  numerator / denominator * 10^estimated_power ==
    //    numerator' / denominator' * 10^(decimal_point - 1)
    // In some cases estimated_power was too low, and this is already the case. We
    // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
    // estimated_power) but do not touch the numerator or denominator.
    // Otherwise the routine multiplies the numerator and the deltas by 10.
    static void FixupMultiply10(int estimated_power, bool is_even,
                                int* decimal_point,
                                Bignum* numerator, Bignum* denominator,
                                Bignum* delta_minus, Bignum* delta_plus) {
        bool in_range;
        if (is_even) {
            // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
            // are rounded to the closest floating-point number with even significand.
            in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
        } else {
            in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
        }
        if (in_range) {
            // Since numerator + delta_plus >= denominator we already have
            // 1 <= numerator/denominator < 10. Simply update the estimated_power.
            *decimal_point = estimated_power + 1;
        } else {
            *decimal_point = estimated_power;
            numerator->Times10();
            if (Bignum::Equal(*delta_minus, *delta_plus)) {
                delta_minus->Times10();
                delta_plus->AssignBignum(*delta_minus);
            } else {
                delta_minus->Times10();
                delta_plus->Times10();
            }
        }
    }

}  // namespace double_conversion

} // namespace WTF
