// 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 <stdarg.h>
#include <limits.h>

#include "strtod.h"
#include "bignum.h"
#include "cached-powers.h"
#include "double.h"

namespace WTF {

namespace double_conversion {

    // 2^53 = 9007199254740992.
    // Any integer with at most 15 decimal digits will hence fit into a double
    // (which has a 53bit significand) without loss of precision.
    static const int kMaxExactDoubleIntegerDecimalDigits = 15;
    // 2^64 = 18446744073709551616 > 10^19
    static const int kMaxUint64DecimalDigits = 19;

    // Max double: 1.7976931348623157 x 10^308
    // Min non-zero double: 4.9406564584124654 x 10^-324
    // Any x >= 10^309 is interpreted as +infinity.
    // Any x <= 10^-324 is interpreted as 0.
    // Note that 2.5e-324 (despite being smaller than the min double) will be read
    // as non-zero (equal to the min non-zero double).
    static const int kMaxDecimalPower = 309;
    static const int kMinDecimalPower = -324;

    // 2^64 = 18446744073709551616
    static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);


    static const double exact_powers_of_ten[] = {
        1.0,  // 10^0
        10.0,
        100.0,
        1000.0,
        10000.0,
        100000.0,
        1000000.0,
        10000000.0,
        100000000.0,
        1000000000.0,
        10000000000.0,  // 10^10
        100000000000.0,
        1000000000000.0,
        10000000000000.0,
        100000000000000.0,
        1000000000000000.0,
        10000000000000000.0,
        100000000000000000.0,
        1000000000000000000.0,
        10000000000000000000.0,
        100000000000000000000.0,  // 10^20
        1000000000000000000000.0,
        // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
        10000000000000000000000.0
    };
    static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);

    // Maximum number of significant digits in the decimal representation.
    // In fact the value is 772 (see conversions.cc), but to give us some margin
    // we round up to 780.
    static const int kMaxSignificantDecimalDigits = 780;

    static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
        for (int i = 0; i < buffer.length(); i++) {
            if (buffer[i] != '0') {
                return buffer.SubVector(i, buffer.length());
            }
        }
        return Vector<const char>(buffer.start(), 0);
    }


    static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
        for (int i = buffer.length() - 1; i >= 0; --i) {
            if (buffer[i] != '0') {
                return buffer.SubVector(0, i + 1);
            }
        }
        return Vector<const char>(buffer.start(), 0);
    }


    static void TrimToMaxSignificantDigits(Vector<const char> buffer,
                                           int exponent,
                                           char* significant_buffer,
                                           int* significant_exponent) {
        for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
            significant_buffer[i] = buffer[i];
        }
        // The input buffer has been trimmed. Therefore the last digit must be
        // different from '0'.
        ASSERT(buffer[buffer.length() - 1] != '0');
        // Set the last digit to be non-zero. This is sufficient to guarantee
        // correct rounding.
        significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
        *significant_exponent =
        exponent + (buffer.length() - kMaxSignificantDecimalDigits);
    }

    // Reads digits from the buffer and converts them to a uint64.
    // Reads in as many digits as fit into a uint64.
    // When the string starts with "1844674407370955161" no further digit is read.
    // Since 2^64 = 18446744073709551616 it would still be possible read another
    // digit if it was less or equal than 6, but this would complicate the code.
    static uint64_t ReadUint64(Vector<const char> buffer,
                               int* number_of_read_digits) {
        uint64_t result = 0;
        int i = 0;
        while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
            int digit = buffer[i++] - '0';
            ASSERT(0 <= digit && digit <= 9);
            result = 10 * result + digit;
        }
        *number_of_read_digits = i;
        return result;
    }


    // Reads a DiyFp from the buffer.
    // The returned DiyFp is not necessarily normalized.
    // If remaining_decimals is zero then the returned DiyFp is accurate.
    // Otherwise it has been rounded and has error of at most 1/2 ulp.
    static void ReadDiyFp(Vector<const char> buffer,
                          DiyFp* result,
                          int* remaining_decimals) {
        int read_digits;
        uint64_t significand = ReadUint64(buffer, &read_digits);
        if (buffer.length() == read_digits) {
            *result = DiyFp(significand, 0);
            *remaining_decimals = 0;
        } else {
            // Round the significand.
            if (buffer[read_digits] >= '5') {
                significand++;
            }
            // Compute the binary exponent.
            int exponent = 0;
            *result = DiyFp(significand, exponent);
            *remaining_decimals = buffer.length() - read_digits;
        }
    }


    static bool DoubleStrtod(Vector<const char> trimmed,
                             int exponent,
                             double* result) {
#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
        // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
        // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
        // result is not accurate.
        // We know that Windows32 uses 64 bits and is therefore accurate.
        // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
        // the same problem.
        return false;
#endif
        if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
            int read_digits;
            // The trimmed input fits into a double.
            // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
            // can compute the result-double simply by multiplying (resp. dividing) the
            // two numbers.
            // This is possible because IEEE guarantees that floating-point operations
            // return the best possible approximation.
            if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
                // 10^-exponent fits into a double.
                *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
                ASSERT(read_digits == trimmed.length());
                *result /= exact_powers_of_ten[-exponent];
                return true;
            }
            if (0 <= exponent && exponent < kExactPowersOfTenSize) {
                // 10^exponent fits into a double.
                *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
                ASSERT(read_digits == trimmed.length());
                *result *= exact_powers_of_ten[exponent];
                return true;
            }
            int remaining_digits =
            kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
            if ((0 <= exponent) &&
                (exponent - remaining_digits < kExactPowersOfTenSize)) {
                // The trimmed string was short and we can multiply it with
                // 10^remaining_digits. As a result the remaining exponent now fits
                // into a double too.
                *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
                ASSERT(read_digits == trimmed.length());
                *result *= exact_powers_of_ten[remaining_digits];
                *result *= exact_powers_of_ten[exponent - remaining_digits];
                return true;
            }
        }
        return false;
    }


    // Returns 10^exponent as an exact DiyFp.
    // The given exponent must be in the range [1; kDecimalExponentDistance[.
    static DiyFp AdjustmentPowerOfTen(int exponent) {
        ASSERT(0 < exponent);
        ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
        // Simply hardcode the remaining powers for the given decimal exponent
        // distance.
        ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
        switch (exponent) {
            case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
            case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
            case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
            case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
            case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
            case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
            case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
            default:
                UNREACHABLE();
                return DiyFp(0, 0);
        }
    }


    // If the function returns true then the result is the correct double.
    // Otherwise it is either the correct double or the double that is just below
    // the correct double.
    static bool DiyFpStrtod(Vector<const char> buffer,
                            int exponent,
                            double* result) {
        DiyFp input;
        int remaining_decimals;
        ReadDiyFp(buffer, &input, &remaining_decimals);
        // Since we may have dropped some digits the input is not accurate.
        // If remaining_decimals is different than 0 than the error is at most
        // .5 ulp (unit in the last place).
        // We don't want to deal with fractions and therefore keep a common
        // denominator.
        const int kDenominatorLog = 3;
        const int kDenominator = 1 << kDenominatorLog;
        // Move the remaining decimals into the exponent.
        exponent += remaining_decimals;
        int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);

        int old_e = input.e();
        input.Normalize();
        error <<= old_e - input.e();

        ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
        if (exponent < PowersOfTenCache::kMinDecimalExponent) {
            *result = 0.0;
            return true;
        }
        DiyFp cached_power;
        int cached_decimal_exponent;
        PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent,
                                                           &cached_power,
                                                           &cached_decimal_exponent);

        if (cached_decimal_exponent != exponent) {
            int adjustment_exponent = exponent - cached_decimal_exponent;
            DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
            input.Multiply(adjustment_power);
            if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
                // The product of input with the adjustment power fits into a 64 bit
                // integer.
                ASSERT(DiyFp::kSignificandSize == 64);
            } else {
                // The adjustment power is exact. There is hence only an error of 0.5.
                error += kDenominator / 2;
            }
        }

        input.Multiply(cached_power);
        // The error introduced by a multiplication of a*b equals
        //   error_a + error_b + error_a*error_b/2^64 + 0.5
        // Substituting a with 'input' and b with 'cached_power' we have
        //   error_b = 0.5  (all cached powers have an error of less than 0.5 ulp),
        //   error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
        int error_b = kDenominator / 2;
        int error_ab = (error == 0 ? 0 : 1);  // We round up to 1.
        int fixed_error = kDenominator / 2;
        error += error_b + error_ab + fixed_error;

        old_e = input.e();
        input.Normalize();
        error <<= old_e - input.e();

        // See if the double's significand changes if we add/subtract the error.
        int order_of_magnitude = DiyFp::kSignificandSize + input.e();
        int effective_significand_size =
        Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
        int precision_digits_count =
        DiyFp::kSignificandSize - effective_significand_size;
        if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
            // This can only happen for very small denormals. In this case the
            // half-way multiplied by the denominator exceeds the range of an uint64.
            // Simply shift everything to the right.
            int shift_amount = (precision_digits_count + kDenominatorLog) -
            DiyFp::kSignificandSize + 1;
            input.set_f(input.f() >> shift_amount);
            input.set_e(input.e() + shift_amount);
            // We add 1 for the lost precision of error, and kDenominator for
            // the lost precision of input.f().
            error = (error >> shift_amount) + 1 + kDenominator;
            precision_digits_count -= shift_amount;
        }
        // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
        ASSERT(DiyFp::kSignificandSize == 64);
        ASSERT(precision_digits_count < 64);
        uint64_t one64 = 1;
        uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
        uint64_t precision_bits = input.f() & precision_bits_mask;
        uint64_t half_way = one64 << (precision_digits_count - 1);
        precision_bits *= kDenominator;
        half_way *= kDenominator;
        DiyFp rounded_input(input.f() >> precision_digits_count,
                            input.e() + precision_digits_count);
        if (precision_bits >= half_way + error) {
            rounded_input.set_f(rounded_input.f() + 1);
        }
        // If the last_bits are too close to the half-way case than we are too
        // inaccurate and round down. In this case we return false so that we can
        // fall back to a more precise algorithm.

        *result = Double(rounded_input).value();
        if (half_way - error < precision_bits && precision_bits < half_way + error) {
            // Too imprecise. The caller will have to fall back to a slower version.
            // However the returned number is guaranteed to be either the correct
            // double, or the next-lower double.
            return false;
        } else {
            return true;
        }
    }


    // Returns the correct double for the buffer*10^exponent.
    // The variable guess should be a close guess that is either the correct double
    // or its lower neighbor (the nearest double less than the correct one).
    // Preconditions:
    //   buffer.length() + exponent <= kMaxDecimalPower + 1
    //   buffer.length() + exponent > kMinDecimalPower
    //   buffer.length() <= kMaxDecimalSignificantDigits
    static double BignumStrtod(Vector<const char> buffer,
                               int exponent,
                               double guess) {
        if (guess == Double::Infinity()) {
            return guess;
        }

        DiyFp upper_boundary = Double(guess).UpperBoundary();

        ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
        ASSERT(buffer.length() + exponent > kMinDecimalPower);
        ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
        // Make sure that the Bignum will be able to hold all our numbers.
        // Our Bignum implementation has a separate field for exponents. Shifts will
        // consume at most one bigit (< 64 bits).
        // ln(10) == 3.3219...
        ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
        Bignum input;
        Bignum boundary;
        input.AssignDecimalString(buffer);
        boundary.AssignUInt64(upper_boundary.f());
        if (exponent >= 0) {
            input.MultiplyByPowerOfTen(exponent);
        } else {
            boundary.MultiplyByPowerOfTen(-exponent);
        }
        if (upper_boundary.e() > 0) {
            boundary.ShiftLeft(upper_boundary.e());
        } else {
            input.ShiftLeft(-upper_boundary.e());
        }
        int comparison = Bignum::Compare(input, boundary);
        if (comparison < 0) {
            return guess;
        } else if (comparison > 0) {
            return Double(guess).NextDouble();
        } else if ((Double(guess).Significand() & 1) == 0) {
            // Round towards even.
            return guess;
        } else {
            return Double(guess).NextDouble();
        }
    }


    double Strtod(Vector<const char> buffer, int exponent) {
        Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
        Vector<const char> trimmed = TrimTrailingZeros(left_trimmed);
        exponent += left_trimmed.length() - trimmed.length();
        if (trimmed.length() == 0) return 0.0;
        if (trimmed.length() > kMaxSignificantDecimalDigits) {
            char significant_buffer[kMaxSignificantDecimalDigits];
            int significant_exponent;
            TrimToMaxSignificantDigits(trimmed, exponent,
                                       significant_buffer, &significant_exponent);
            return Strtod(Vector<const char>(significant_buffer,
                                             kMaxSignificantDecimalDigits),
                          significant_exponent);
        }
        if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
            return Double::Infinity();
        }
        if (exponent + trimmed.length() <= kMinDecimalPower) {
            return 0.0;
        }

        double guess;
        if (DoubleStrtod(trimmed, exponent, &guess) ||
            DiyFpStrtod(trimmed, exponent, &guess)) {
            return guess;
        }
        return BignumStrtod(trimmed, exponent, guess);
    }

}  // namespace double_conversion

} // namespace WTF
