/*
 * Copyright (C) 2012 Google Inc. 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 "Decimal.h"
#include "moz-decimal-utils.h"

#include <algorithm>
#include <float.h>

#if defined(STARBOARD)
#include "starboard/double.h"
#endif

namespace WebCore {

namespace DecimalPrivate {

static int const ExponentMax = 1023;
static int const ExponentMin = -1023;
static int const Precision = 18;

static const uint64_t MaxCoefficient = UINT64_C(0x16345785D89FFFF); // 999999999999999999 == 18 9's

// This class handles Decimal special values.
class SpecialValueHandler {
    WTF_MAKE_NONCOPYABLE(SpecialValueHandler);
public:
    enum HandleResult {
        BothFinite,
        BothInfinity,
        EitherNaN,
        LHSIsInfinity,
        RHSIsInfinity,
    };

    SpecialValueHandler(const Decimal& lhs, const Decimal& rhs);
    HandleResult handle();
    Decimal value() const;

private:
    enum Result {
        ResultIsLHS,
        ResultIsRHS,
        ResultIsUnknown,
    };

    const Decimal& m_lhs;
    const Decimal& m_rhs;
    Result m_result;
};

SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs)
    : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown)
{
}

SpecialValueHandler::HandleResult SpecialValueHandler::handle()
{
    if (m_lhs.isFinite() && m_rhs.isFinite())
        return BothFinite;

    const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass();
    const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass();
    if (lhsClass == Decimal::EncodedData::ClassNaN) {
        m_result = ResultIsLHS;
        return EitherNaN;
     }

    if (rhsClass == Decimal::EncodedData::ClassNaN) {
        m_result = ResultIsRHS;
        return EitherNaN;
     }

    if (lhsClass == Decimal::EncodedData::ClassInfinity)
        return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity;

    if (rhsClass == Decimal::EncodedData::ClassInfinity)
        return RHSIsInfinity;

    ASSERT_NOT_REACHED();
    return BothFinite;
}

Decimal SpecialValueHandler::value() const
{
    switch (m_result) {
    case ResultIsLHS:
        return m_lhs;
    case ResultIsRHS:
        return m_rhs;
    case ResultIsUnknown:
    default:
        ASSERT_NOT_REACHED();
        return m_lhs;
    }
}

// This class is used for 128 bit unsigned integer arithmetic.
class UInt128 {
public:
    UInt128(uint64_t low, uint64_t high)
        : m_high(high), m_low(low)
    {
    }

    UInt128& operator/=(uint32_t);

    uint64_t high() const { return m_high; }
    uint64_t low() const { return m_low; }

    static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); }

private:
    static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); }
    static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); }
    bool isZero() const { return !m_low && !m_high; }
    static uint64_t makeUInt64(uint32_t low, uint32_t high) { return low | (static_cast<uint64_t>(high) << 32); }

    static uint64_t multiplyHigh(uint64_t, uint64_t);

    uint64_t m_high;
    uint64_t m_low;
};

UInt128& UInt128::operator/=(const uint32_t divisor)
{
    ASSERT(divisor);

    if (!m_high) {
        m_low /= divisor;
        return *this;
    }

    uint32_t dividend[4];
    dividend[0] = lowUInt32(m_low);
    dividend[1] = highUInt32(m_low);
    dividend[2] = lowUInt32(m_high);
    dividend[3] = highUInt32(m_high);

    uint32_t quotient[4];
    uint32_t remainder = 0;
    for (int i = 3; i >= 0; --i) {
        const uint64_t work = makeUInt64(dividend[i], remainder);
        remainder = static_cast<uint32_t>(work % divisor);
        quotient[i] = static_cast<uint32_t>(work / divisor);
    }
    m_low = makeUInt64(quotient[0], quotient[1]);
    m_high = makeUInt64(quotient[2], quotient[3]);
    return *this;
}

// Returns high 64bit of 128bit product.
uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v)
{
    const uint64_t uLow = lowUInt32(u);
    const uint64_t uHigh = highUInt32(u);
    const uint64_t vLow = lowUInt32(v);
    const uint64_t vHigh = highUInt32(v);
    const uint64_t partialProduct = uHigh * vLow + highUInt32(uLow * vLow);
    return uHigh * vHigh + highUInt32(partialProduct) + highUInt32(uLow * vHigh + lowUInt32(partialProduct));
}

static int countDigits(uint64_t x)
{
    int numberOfDigits = 0;
    for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) {
        ++numberOfDigits;
        if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10)
            break;
    }
    return numberOfDigits;
}

static uint64_t scaleDown(uint64_t x, int n)
{
    ASSERT(n >= 0);
    while (n > 0 && x) {
        x /= 10;
        --n;
    }
    return x;
}

static uint64_t scaleUp(uint64_t x, int n)
{
    ASSERT(n >= 0);
    ASSERT(n < Precision);

    uint64_t y = 1;
    uint64_t z = 10;
    for (;;) {
        if (n & 1)
            y = y * z;

        n >>= 1;
        if (!n)
            return x * y;

        z = z * z;
    }
}

} // namespace DecimalPrivate

using namespace DecimalPrivate;

Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass)
    : m_coefficient(0)
    , m_exponent(0)
    , m_formatClass(formatClass)
    , m_sign(sign)
{
}

Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient)
    : m_formatClass(coefficient ? ClassNormal : ClassZero)
    , m_sign(sign)
{
    if (exponent >= ExponentMin && exponent <= ExponentMax) {
        while (coefficient > MaxCoefficient) {
            coefficient /= 10;
            ++exponent;
        }
    }

    if (exponent > ExponentMax) {
        m_coefficient = 0;
        m_exponent = 0;
        m_formatClass = ClassInfinity;
        return;
    }

    if (exponent < ExponentMin) {
        m_coefficient = 0;
        m_exponent = 0;
        m_formatClass = ClassZero;
        return;
    }

    m_coefficient = coefficient;
    m_exponent = static_cast<int16_t>(exponent);
}

bool Decimal::EncodedData::operator==(const EncodedData& another) const
{
    return m_sign == another.m_sign
        && m_formatClass == another.m_formatClass
        && m_exponent == another.m_exponent
        && m_coefficient == another.m_coefficient;
}

Decimal::Decimal(int32_t i32)
    : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32))
{
}

Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
    : m_data(sign, coefficient ? exponent : 0, coefficient)
{
}

Decimal::Decimal(const EncodedData& data)
    : m_data(data)
{
}

Decimal::Decimal(const Decimal& other)
    : m_data(other.m_data)
{
}

Decimal& Decimal::operator=(const Decimal& other)
{
    m_data = other.m_data;
    return *this;
}

Decimal& Decimal::operator+=(const Decimal& other)
{
    m_data = (*this + other).m_data;
    return *this;
}

Decimal& Decimal::operator-=(const Decimal& other)
{
    m_data = (*this - other).m_data;
    return *this;
}

Decimal& Decimal::operator*=(const Decimal& other)
{
    m_data = (*this * other).m_data;
    return *this;
}

Decimal& Decimal::operator/=(const Decimal& other)
{
    m_data = (*this / other).m_data;
    return *this;
}

Decimal Decimal::operator-() const
{
    if (isNaN())
        return *this;

    Decimal result(*this);
    result.m_data.setSign(invertSign(m_data.sign()));
    return result;
}

Decimal Decimal::operator+(const Decimal& rhs) const
{
    const Decimal& lhs = *this;
    const Sign lhsSign = lhs.sign();
    const Sign rhsSign = rhs.sign();

    SpecialValueHandler handler(lhs, rhs);
    switch (handler.handle()) {
    case SpecialValueHandler::BothFinite:
        break;

    case SpecialValueHandler::BothInfinity:
        return lhsSign == rhsSign ? lhs : nan();

    case SpecialValueHandler::EitherNaN:
        return handler.value();

    case SpecialValueHandler::LHSIsInfinity:
        return lhs;

    case SpecialValueHandler::RHSIsInfinity:
        return rhs;
    }

    const AlignedOperands alignedOperands = alignOperands(lhs, rhs);

    const uint64_t result = lhsSign == rhsSign
        ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient
        : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient;

    if (lhsSign == Negative && rhsSign == Positive && !result)
        return Decimal(Positive, alignedOperands.exponent, 0);

    return static_cast<int64_t>(result) >= 0
        ? Decimal(lhsSign, alignedOperands.exponent, result)
        : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result));
}

Decimal Decimal::operator-(const Decimal& rhs) const
{
    const Decimal& lhs = *this;
    const Sign lhsSign = lhs.sign();
    const Sign rhsSign = rhs.sign();

    SpecialValueHandler handler(lhs, rhs);
    switch (handler.handle()) {
    case SpecialValueHandler::BothFinite:
        break;

    case SpecialValueHandler::BothInfinity:
        return lhsSign == rhsSign ? nan() : lhs;

    case SpecialValueHandler::EitherNaN:
        return handler.value();

    case SpecialValueHandler::LHSIsInfinity:
        return lhs;

    case SpecialValueHandler::RHSIsInfinity:
        return infinity(invertSign(rhsSign));
    }

    const AlignedOperands alignedOperands = alignOperands(lhs, rhs);

    const uint64_t result = lhsSign == rhsSign
        ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient
        : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient;

    if (lhsSign == Negative && rhsSign == Negative && !result)
        return Decimal(Positive, alignedOperands.exponent, 0);

    return static_cast<int64_t>(result) >= 0
        ? Decimal(lhsSign, alignedOperands.exponent, result)
        : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result));
}

Decimal Decimal::operator*(const Decimal& rhs) const
{
    const Decimal& lhs = *this;
    const Sign lhsSign = lhs.sign();
    const Sign rhsSign = rhs.sign();
    const Sign resultSign = lhsSign == rhsSign ? Positive : Negative;

    SpecialValueHandler handler(lhs, rhs);
    switch (handler.handle()) {
    case SpecialValueHandler::BothFinite: {
        const uint64_t lhsCoefficient = lhs.m_data.coefficient();
        const uint64_t rhsCoefficient = rhs.m_data.coefficient();
        int resultExponent = lhs.exponent() + rhs.exponent();
        UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient));
        while (work.high()) {
            work /= 10;
            ++resultExponent;
        }
        return Decimal(resultSign, resultExponent, work.low());
    }

    case SpecialValueHandler::BothInfinity:
        return infinity(resultSign);

    case SpecialValueHandler::EitherNaN:
        return handler.value();

    case SpecialValueHandler::LHSIsInfinity:
        return rhs.isZero() ? nan() : infinity(resultSign);

    case SpecialValueHandler::RHSIsInfinity:
        return lhs.isZero() ? nan() : infinity(resultSign);
    }

    ASSERT_NOT_REACHED();
    return nan();
}

Decimal Decimal::operator/(const Decimal& rhs) const
{
    const Decimal& lhs = *this;
    const Sign lhsSign = lhs.sign();
    const Sign rhsSign = rhs.sign();
    const Sign resultSign = lhsSign == rhsSign ? Positive : Negative;

    SpecialValueHandler handler(lhs, rhs);
    switch (handler.handle()) {
    case SpecialValueHandler::BothFinite:
        break;

    case SpecialValueHandler::BothInfinity:
        return nan();

    case SpecialValueHandler::EitherNaN:
        return handler.value();

    case SpecialValueHandler::LHSIsInfinity:
        return infinity(resultSign);

    case SpecialValueHandler::RHSIsInfinity:
        return zero(resultSign);
    }

    ASSERT(lhs.isFinite());
    ASSERT(rhs.isFinite());

    if (rhs.isZero())
        return lhs.isZero() ? nan() : infinity(resultSign);

    int resultExponent = lhs.exponent() - rhs.exponent();

    if (lhs.isZero())
        return Decimal(resultSign, resultExponent, 0);

    uint64_t remainder = lhs.m_data.coefficient();
    const uint64_t divisor = rhs.m_data.coefficient();
    uint64_t result = 0;
    while (result < MaxCoefficient / 100) {
        while (remainder < divisor) {
            remainder *= 10;
            result *= 10;
            --resultExponent;
        }
        result += remainder / divisor;
        remainder %= divisor;
        if (!remainder)
            break;
    }

    if (remainder > divisor / 2)
        ++result;

    return Decimal(resultSign, resultExponent, result);
}

bool Decimal::operator==(const Decimal& rhs) const
{
    if (isNaN() || rhs.isNaN())
        return false;
    return m_data == rhs.m_data || compareTo(rhs).isZero();
}

bool Decimal::operator!=(const Decimal& rhs) const
{
    if (isNaN() || rhs.isNaN())
        return true;
    if (m_data == rhs.m_data)
        return false;
    const Decimal result = compareTo(rhs);
    if (result.isNaN())
        return false;
    return !result.isZero();
}

bool Decimal::operator<(const Decimal& rhs) const
{
    const Decimal result = compareTo(rhs);
    if (result.isNaN())
        return false;
    return !result.isZero() && result.isNegative();
}

bool Decimal::operator<=(const Decimal& rhs) const
{
    if (isNaN() || rhs.isNaN())
        return false;
    if (m_data == rhs.m_data)
        return true;
    const Decimal result = compareTo(rhs);
    if (result.isNaN())
        return false;
    return result.isZero() || result.isNegative();
}

bool Decimal::operator>(const Decimal& rhs) const
{
    const Decimal result = compareTo(rhs);
    if (result.isNaN())
        return false;
    return !result.isZero() && result.isPositive();
}

bool Decimal::operator>=(const Decimal& rhs) const
{
    if (isNaN() || rhs.isNaN())
        return false;
    if (m_data == rhs.m_data)
        return true;
    const Decimal result = compareTo(rhs);
    if (result.isNaN())
        return false;
    return result.isZero() || !result.isNegative();
}

Decimal Decimal::abs() const
{
    Decimal result(*this);
    result.m_data.setSign(Positive);
    return result;
}

Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs)
{
    ASSERT(lhs.isFinite());
    ASSERT(rhs.isFinite());

    const int lhsExponent = lhs.exponent();
    const int rhsExponent = rhs.exponent();
    int exponent = std::min(lhsExponent, rhsExponent);
    uint64_t lhsCoefficient = lhs.m_data.coefficient();
    uint64_t rhsCoefficient = rhs.m_data.coefficient();

    if (lhsExponent > rhsExponent) {
        const int numberOfLHSDigits = countDigits(lhsCoefficient);
        if (numberOfLHSDigits) {
            const int lhsShiftAmount = lhsExponent - rhsExponent;
            const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision;
            if (overflow <= 0)
                lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount);
            else {
                lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow);
                rhsCoefficient = scaleDown(rhsCoefficient, overflow);
                exponent += overflow;
            }
        }

    } else if (lhsExponent < rhsExponent) {
        const int numberOfRHSDigits = countDigits(rhsCoefficient);
        if (numberOfRHSDigits) {
            const int rhsShiftAmount = rhsExponent - lhsExponent;
            const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision;
            if (overflow <= 0)
                rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount);
            else {
                rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow);
                lhsCoefficient = scaleDown(lhsCoefficient, overflow);
                exponent += overflow;
            }
        }
    }

    AlignedOperands alignedOperands;
    alignedOperands.exponent = exponent;
    alignedOperands.lhsCoefficient = lhsCoefficient;
    alignedOperands.rhsCoefficient = rhsCoefficient;
    return alignedOperands;
}

// Round toward positive infinity.
// Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" here.
Decimal Decimal::ceiling() const
{
    if (isSpecial())
        return *this;

    if (exponent() >= 0)
        return *this;

    uint64_t coefficient = m_data.coefficient();
    const int numberOfDigits = countDigits(coefficient);
    const int numberOfDropDigits = -exponent();
    if (numberOfDigits < numberOfDropDigits)
        return isPositive() ? Decimal(1) : zero(Positive);

    uint64_t result = scaleDown(coefficient, numberOfDropDigits);
    uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits);
    if (droppedDigits && isPositive())
        result += 1;
    return Decimal(sign(), 0, result);
}

Decimal Decimal::compareTo(const Decimal& rhs) const
{
    const Decimal result(*this - rhs);
    switch (result.m_data.formatClass()) {
    case EncodedData::ClassInfinity:
        return result.isNegative() ? Decimal(-1) : Decimal(1);

    case EncodedData::ClassNaN:
    case EncodedData::ClassNormal:
        return result;

    case EncodedData::ClassZero:
        return zero(Positive);

    default:
        ASSERT_NOT_REACHED();
        return nan();
    }
}

// Round toward negative infinity.
Decimal Decimal::floor() const
{
    if (isSpecial())
        return *this;

    if (exponent() >= 0)
        return *this;

    uint64_t coefficient = m_data.coefficient();
    const int numberOfDigits = countDigits(coefficient);
    const int numberOfDropDigits = -exponent();
    if (numberOfDigits < numberOfDropDigits)
        return isPositive() ? zero(Positive) : Decimal(-1);

    uint64_t result = scaleDown(coefficient, numberOfDropDigits);
    uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits);
    if (droppedDigits && isNegative()) {
        result += 1;
    }
    return Decimal(sign(), 0, result);
}

Decimal Decimal::fromDouble(double doubleValue)
{
#if defined(STARBOARD)
    if (SbDoubleIsFinite(doubleValue))
        return fromString(mozToString(doubleValue));
    if (SbDoubleIsNan(doubleValue))
        return nan();
    return infinity(doubleValue < 0 ? Negative : Positive);
#else
    if (std::isfinite(doubleValue))
        return fromString(mozToString(doubleValue));
    if (std::isinf(doubleValue))
        return infinity(doubleValue < 0 ? Negative : Positive);
    return nan();
#endif
}

Decimal Decimal::fromString(const String& str)
{
    int exponent = 0;
    Sign exponentSign = Positive;
    int numberOfDigits = 0;
    int numberOfDigitsAfterDot = 0;
    int numberOfExtraDigits = 0;
    Sign sign = Positive;

    enum {
        StateDigit,
        StateDot,
        StateDotDigit,
        StateE,
        StateEDigit,
        StateESign,
        StateSign,
        StateStart,
        StateZero,
    } state = StateStart;

#define HandleCharAndBreak(expected, nextState) \
    if (ch == expected) { \
        state = nextState; \
        break; \
    }

#define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
    if (ch == expected1 || ch == expected2) { \
        state = nextState; \
        break; \
    }

    uint64_t accumulator = 0;
    for (unsigned index = 0; index < str.length(); ++index) {
        const int ch = str[index];
        switch (state) {
        case StateDigit:
            if (ch >= '0' && ch <= '9') {
                if (numberOfDigits < Precision) {
                    ++numberOfDigits;
                    accumulator *= 10;
                    accumulator += ch - '0';
                } else
                    ++numberOfExtraDigits;
                break;
            }

            HandleCharAndBreak('.', StateDot);
            HandleTwoCharsAndBreak('E', 'e', StateE);
            return nan();

        case StateDot:
            if (ch >= '0' && ch <= '9') {
                if (numberOfDigits < Precision) {
                    ++numberOfDigits;
                    ++numberOfDigitsAfterDot;
                    accumulator *= 10;
                    accumulator += ch - '0';
                }
                state = StateDotDigit;
                break;
            }

        case StateDotDigit:
            if (ch >= '0' && ch <= '9') {
                if (numberOfDigits < Precision) {
                    ++numberOfDigits;
                    ++numberOfDigitsAfterDot;
                    accumulator *= 10;
                    accumulator += ch - '0';
                }
                break;
            }

            HandleTwoCharsAndBreak('E', 'e', StateE);
            return nan();

        case StateE:
            if (ch == '+') {
                exponentSign = Positive;
                state = StateESign;
                break;
            }

            if (ch == '-') {
                exponentSign = Negative;
                state = StateESign;
                break;
            }

            if (ch >= '0' && ch <= '9') {
                exponent = ch - '0';
                state = StateEDigit;
                break;
            }

            return nan();

        case StateEDigit:
            if (ch >= '0' && ch <= '9') {
                exponent *= 10;
                exponent += ch - '0';
                if (exponent > ExponentMax + Precision) {
                    if (accumulator)
                        return exponentSign == Negative ? zero(Positive) : infinity(sign);
                    return zero(sign);
                }
                state = StateEDigit;
                break;
            }

            return nan();

        case StateESign:
            if (ch >= '0' && ch <= '9') {
                exponent = ch - '0';
                state = StateEDigit;
                break;
            }

            return nan();

        case StateSign:
            if (ch >= '1' && ch <= '9') {
                accumulator = ch - '0';
                numberOfDigits = 1;
                state = StateDigit;
                break;
            }

            HandleCharAndBreak('0', StateZero);
            return nan();

        case StateStart:
            if (ch >= '1' && ch <= '9') {
                accumulator = ch - '0';
                numberOfDigits = 1;
                state = StateDigit;
                break;
            }

            if (ch == '-') {
                sign = Negative;
                state = StateSign;
                break;
            }

            if (ch == '+') {
                sign = Positive;
                state = StateSign;
                break;
            }

            HandleCharAndBreak('0', StateZero);
            HandleCharAndBreak('.', StateDot);
            return nan();

        case StateZero:
            if (ch == '0')
                break;

            if (ch >= '1' && ch <= '9') {
                accumulator = ch - '0';
                numberOfDigits = 1;
                state = StateDigit;
                break;
            }

            HandleCharAndBreak('.', StateDot);
            HandleTwoCharsAndBreak('E', 'e', StateE);
            return nan();

        default:
            ASSERT_NOT_REACHED();
            return nan();
        }
    }

    if (state == StateZero)
        return zero(sign);

    if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
        int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
        if (resultExponent < ExponentMin)
            return zero(Positive);

        const int overflow = resultExponent - ExponentMax + 1;
        if (overflow > 0) {
            if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision)
                return infinity(sign);
            accumulator = scaleUp(accumulator, overflow);
            resultExponent -= overflow;
        }

        return Decimal(sign, resultExponent, accumulator);
    }

    return nan();
}

Decimal Decimal::infinity(const Sign sign)
{
    return Decimal(EncodedData(sign, EncodedData::ClassInfinity));
}

Decimal Decimal::nan()
{
    return Decimal(EncodedData(Positive, EncodedData::ClassNaN));
}

Decimal Decimal::remainder(const Decimal& rhs) const
{
    const Decimal quotient = *this / rhs;
    return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceiling() : quotient.floor()) * rhs;
}

Decimal Decimal::round() const
{
    if (isSpecial())
        return *this;

    if (exponent() >= 0)
        return *this;

    uint64_t result = m_data.coefficient();
    const int numberOfDigits = countDigits(result);
    const int numberOfDropDigits = -exponent();
    if (numberOfDigits < numberOfDropDigits)
        return zero(Positive);

    // We're implementing round-half-away-from-zero, so we only need the one
    // (the most significant) fractional digit:
    result = scaleDown(result, numberOfDropDigits - 1);
    if (result % 10 >= 5)
        result += 10;
    result /= 10;
    return Decimal(sign(), 0, result);
}

double Decimal::toDouble() const
{
    if (isFinite()) {
        bool valid;
        const double doubleValue = mozToDouble(toString(), &valid);
        return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN();
    }

    if (isInfinity())
        return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();

    return std::numeric_limits<double>::quiet_NaN();
}

String Decimal::toString() const
{
    switch (m_data.formatClass()) {
    case EncodedData::ClassInfinity:
        return sign() ? "-Infinity" : "Infinity";

    case EncodedData::ClassNaN:
        return "NaN";

    case EncodedData::ClassNormal:
    case EncodedData::ClassZero:
        break;

    default:
        ASSERT_NOT_REACHED();
        return "";
    }

    StringBuilder builder;
    if (sign())
        builder.append('-');

    int originalExponent = exponent();
    uint64_t coefficient = m_data.coefficient();

    if (originalExponent < 0) {
        const int maxDigits = DBL_DIG;
        uint64_t lastDigit = 0;
        while (countDigits(coefficient) > maxDigits) {
            lastDigit = coefficient % 10;
            coefficient /= 10;
            ++originalExponent;
        }

        if (lastDigit >= 5)
            ++coefficient;

        while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
            coefficient /= 10;
            ++originalExponent;
        }
    }

    const String digits = mozToString(coefficient);
    int coefficientLength = static_cast<int>(digits.length());
    const int adjustedExponent = originalExponent + coefficientLength - 1;
    if (originalExponent <= 0 && adjustedExponent >= -6) {
        if (!originalExponent) {
            builder.append(digits);
            return builder.toString();
        }

        if (adjustedExponent >= 0) {
            for (int i = 0; i < coefficientLength; ++i) {
                builder.append(digits[i]);
                if (i == adjustedExponent)
                    builder.append('.');
            }
            return builder.toString();
        }

        builder.appendLiteral("0.");
        for (int i = adjustedExponent + 1; i < 0; ++i)
            builder.append('0');

        builder.append(digits);

    } else {
        builder.append(digits[0]);
        while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0')
            --coefficientLength;
        if (coefficientLength >= 2) {
            builder.append('.');
            for (int i = 1; i < coefficientLength; ++i)
                builder.append(digits[i]);
        }

        if (adjustedExponent) {
            builder.append(adjustedExponent < 0 ? "e" : "e+");
            builder.appendNumber(adjustedExponent);
        }
    }
    return builder.toString();
}

bool Decimal::toString(char* strBuf, size_t bufLength) const
{
  ASSERT(bufLength > 0);
  String str = toString();
  size_t length = str.copy(strBuf, bufLength);
  if (length < bufLength) {
    strBuf[length] = '\0';
    return true;
  }
  strBuf[bufLength - 1] = '\0';
  return false;
}

Decimal Decimal::zero(Sign sign)
{
    return Decimal(EncodedData(sign, EncodedData::ClassZero));
}

} // namespace WebCore

