Home | History | Annotate | Download | only in platform
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/platform/Decimal.h"
     33 
     34 #include <float.h>
     35 #include <algorithm>
     36 
     37 #include "wtf/Assertions.h"
     38 #include "wtf/MathExtras.h"
     39 #include "wtf/Noncopyable.h"
     40 #include "wtf/text/StringBuilder.h"
     41 
     42 namespace WebCore {
     43 
     44 namespace DecimalPrivate {
     45 
     46 static int const ExponentMax = 1023;
     47 static int const ExponentMin = -1023;
     48 static int const Precision = 18;
     49 
     50 static const uint64_t MaxCoefficient = UINT64_C(0x16345785D89FFFF); // 999999999999999999 == 18 9's
     51 
     52 // This class handles Decimal special values.
     53 class SpecialValueHandler {
     54     WTF_MAKE_NONCOPYABLE(SpecialValueHandler);
     55 public:
     56     enum HandleResult {
     57         BothFinite,
     58         BothInfinity,
     59         EitherNaN,
     60         LHSIsInfinity,
     61         RHSIsInfinity,
     62     };
     63 
     64     SpecialValueHandler(const Decimal& lhs, const Decimal& rhs);
     65     HandleResult handle();
     66     Decimal value() const;
     67 
     68 private:
     69     enum Result {
     70         ResultIsLHS,
     71         ResultIsRHS,
     72         ResultIsUnknown,
     73     };
     74 
     75     const Decimal& m_lhs;
     76     const Decimal& m_rhs;
     77     Result m_result;
     78 };
     79 
     80 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs)
     81     : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown)
     82 {
     83 }
     84 
     85 SpecialValueHandler::HandleResult SpecialValueHandler::handle()
     86 {
     87     if (m_lhs.isFinite() && m_rhs.isFinite())
     88         return BothFinite;
     89 
     90     const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass();
     91     const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass();
     92     if (lhsClass == Decimal::EncodedData::ClassNaN) {
     93         m_result = ResultIsLHS;
     94         return EitherNaN;
     95      }
     96 
     97     if (rhsClass == Decimal::EncodedData::ClassNaN) {
     98         m_result = ResultIsRHS;
     99         return EitherNaN;
    100      }
    101 
    102     if (lhsClass == Decimal::EncodedData::ClassInfinity)
    103         return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity;
    104 
    105     if (rhsClass == Decimal::EncodedData::ClassInfinity)
    106         return RHSIsInfinity;
    107 
    108     ASSERT_NOT_REACHED();
    109     return BothFinite;
    110 }
    111 
    112 Decimal SpecialValueHandler::value() const
    113 {
    114     switch (m_result) {
    115     case ResultIsLHS:
    116         return m_lhs;
    117     case ResultIsRHS:
    118         return m_rhs;
    119     case ResultIsUnknown:
    120     default:
    121         ASSERT_NOT_REACHED();
    122         return m_lhs;
    123     }
    124 }
    125 
    126 // This class is used for 128 bit unsigned integer arithmetic.
    127 class UInt128 {
    128 public:
    129     UInt128(uint64_t low, uint64_t high)
    130         : m_high(high), m_low(low)
    131     {
    132     }
    133 
    134     UInt128& operator/=(uint32_t);
    135 
    136     uint64_t high() const { return m_high; }
    137     uint64_t low() const { return m_low; }
    138 
    139     static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); }
    140 
    141 private:
    142     static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); }
    143     static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); }
    144     bool isZero() const { return !m_low && !m_high; }
    145     static uint64_t makeUInt64(uint32_t low, uint32_t high) { return low | (static_cast<uint64_t>(high) << 32); }
    146 
    147     static uint64_t multiplyHigh(uint64_t, uint64_t);
    148 
    149     uint64_t m_high;
    150     uint64_t m_low;
    151 };
    152 
    153 UInt128& UInt128::operator/=(const uint32_t divisor)
    154 {
    155     ASSERT(divisor);
    156 
    157     if (!m_high) {
    158         m_low /= divisor;
    159         return *this;
    160     }
    161 
    162     uint32_t dividend[4];
    163     dividend[0] = lowUInt32(m_low);
    164     dividend[1] = highUInt32(m_low);
    165     dividend[2] = lowUInt32(m_high);
    166     dividend[3] = highUInt32(m_high);
    167 
    168     uint32_t quotient[4];
    169     uint32_t remainder = 0;
    170     for (int i = 3; i >= 0; --i) {
    171         const uint64_t work = makeUInt64(dividend[i], remainder);
    172         remainder = static_cast<uint32_t>(work % divisor);
    173         quotient[i] = static_cast<uint32_t>(work / divisor);
    174     }
    175     m_low = makeUInt64(quotient[0], quotient[1]);
    176     m_high = makeUInt64(quotient[2], quotient[3]);
    177     return *this;
    178 }
    179 
    180 // Returns high 64bit of 128bit product.
    181 uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v)
    182 {
    183     const uint64_t uLow = lowUInt32(u);
    184     const uint64_t uHigh = highUInt32(u);
    185     const uint64_t vLow = lowUInt32(v);
    186     const uint64_t vHigh = highUInt32(v);
    187     const uint64_t partialProduct = uHigh * vLow + highUInt32(uLow * vLow);
    188     return uHigh * vHigh + highUInt32(partialProduct) + highUInt32(uLow * vHigh + lowUInt32(partialProduct));
    189 }
    190 
    191 static int countDigits(uint64_t x)
    192 {
    193     int numberOfDigits = 0;
    194     for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) {
    195         ++numberOfDigits;
    196         if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10)
    197             break;
    198     }
    199     return numberOfDigits;
    200 }
    201 
    202 static uint64_t scaleDown(uint64_t x, int n)
    203 {
    204     ASSERT(n >= 0);
    205     while (n > 0 && x) {
    206         x /= 10;
    207         --n;
    208     }
    209     return x;
    210 }
    211 
    212 static uint64_t scaleUp(uint64_t x, int n)
    213 {
    214     ASSERT(n >= 0);
    215     ASSERT(n < Precision);
    216 
    217     uint64_t y = 1;
    218     uint64_t z = 10;
    219     for (;;) {
    220         if (n & 1)
    221             y = y * z;
    222 
    223         n >>= 1;
    224         if (!n)
    225             return x * y;
    226 
    227         z = z * z;
    228     }
    229 }
    230 
    231 } // namespace DecimalPrivate
    232 
    233 using namespace DecimalPrivate;
    234 
    235 Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass)
    236     : m_coefficient(0)
    237     , m_exponent(0)
    238     , m_formatClass(formatClass)
    239     , m_sign(sign)
    240 {
    241 }
    242 
    243 Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient)
    244     : m_formatClass(coefficient ? ClassNormal : ClassZero)
    245     , m_sign(sign)
    246 {
    247     if (exponent >= ExponentMin && exponent <= ExponentMax) {
    248         while (coefficient > MaxCoefficient) {
    249             coefficient /= 10;
    250             ++exponent;
    251         }
    252     }
    253 
    254     if (exponent > ExponentMax) {
    255         m_coefficient = 0;
    256         m_exponent = 0;
    257         m_formatClass = ClassInfinity;
    258         return;
    259     }
    260 
    261     if (exponent < ExponentMin) {
    262         m_coefficient = 0;
    263         m_exponent = 0;
    264         m_formatClass = ClassZero;
    265         return;
    266     }
    267 
    268     m_coefficient = coefficient;
    269     m_exponent = static_cast<int16_t>(exponent);
    270 }
    271 
    272 bool Decimal::EncodedData::operator==(const EncodedData& another) const
    273 {
    274     return m_sign == another.m_sign
    275         && m_formatClass == another.m_formatClass
    276         && m_exponent == another.m_exponent
    277         && m_coefficient == another.m_coefficient;
    278 }
    279 
    280 Decimal::Decimal(int32_t i32)
    281     : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32))
    282 {
    283 }
    284 
    285 Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
    286     : m_data(sign, exponent, coefficient)
    287 {
    288 }
    289 
    290 Decimal::Decimal(const EncodedData& data)
    291     : m_data(data)
    292 {
    293 }
    294 
    295 Decimal::Decimal(const Decimal& other)
    296     : m_data(other.m_data)
    297 {
    298 }
    299 
    300 Decimal& Decimal::operator=(const Decimal& other)
    301 {
    302     m_data = other.m_data;
    303     return *this;
    304 }
    305 
    306 Decimal& Decimal::operator+=(const Decimal& other)
    307 {
    308     m_data = (*this + other).m_data;
    309     return *this;
    310 }
    311 
    312 Decimal& Decimal::operator-=(const Decimal& other)
    313 {
    314     m_data = (*this - other).m_data;
    315     return *this;
    316 }
    317 
    318 Decimal& Decimal::operator*=(const Decimal& other)
    319 {
    320     m_data = (*this * other).m_data;
    321     return *this;
    322 }
    323 
    324 Decimal& Decimal::operator/=(const Decimal& other)
    325 {
    326     m_data = (*this / other).m_data;
    327     return *this;
    328 }
    329 
    330 Decimal Decimal::operator-() const
    331 {
    332     if (isNaN())
    333         return *this;
    334 
    335     Decimal result(*this);
    336     result.m_data.setSign(invertSign(m_data.sign()));
    337     return result;
    338 }
    339 
    340 Decimal Decimal::operator+(const Decimal& rhs) const
    341 {
    342     const Decimal& lhs = *this;
    343     const Sign lhsSign = lhs.sign();
    344     const Sign rhsSign = rhs.sign();
    345 
    346     SpecialValueHandler handler(lhs, rhs);
    347     switch (handler.handle()) {
    348     case SpecialValueHandler::BothFinite:
    349         break;
    350 
    351     case SpecialValueHandler::BothInfinity:
    352         return lhsSign == rhsSign ? lhs : nan();
    353 
    354     case SpecialValueHandler::EitherNaN:
    355         return handler.value();
    356 
    357     case SpecialValueHandler::LHSIsInfinity:
    358         return lhs;
    359 
    360     case SpecialValueHandler::RHSIsInfinity:
    361         return rhs;
    362     }
    363 
    364     const AlignedOperands alignedOperands = alignOperands(lhs, rhs);
    365 
    366     const uint64_t result = lhsSign == rhsSign
    367         ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient
    368         : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient;
    369 
    370     if (lhsSign == Negative && rhsSign == Positive && !result)
    371         return Decimal(Positive, alignedOperands.exponent, 0);
    372 
    373     return static_cast<int64_t>(result) >= 0
    374         ? Decimal(lhsSign, alignedOperands.exponent, result)
    375         : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result));
    376 }
    377 
    378 Decimal Decimal::operator-(const Decimal& rhs) const
    379 {
    380     const Decimal& lhs = *this;
    381     const Sign lhsSign = lhs.sign();
    382     const Sign rhsSign = rhs.sign();
    383 
    384     SpecialValueHandler handler(lhs, rhs);
    385     switch (handler.handle()) {
    386     case SpecialValueHandler::BothFinite:
    387         break;
    388 
    389     case SpecialValueHandler::BothInfinity:
    390         return lhsSign == rhsSign ? nan() : lhs;
    391 
    392     case SpecialValueHandler::EitherNaN:
    393         return handler.value();
    394 
    395     case SpecialValueHandler::LHSIsInfinity:
    396         return lhs;
    397 
    398     case SpecialValueHandler::RHSIsInfinity:
    399         return infinity(invertSign(rhsSign));
    400     }
    401 
    402     const AlignedOperands alignedOperands = alignOperands(lhs, rhs);
    403 
    404     const uint64_t result = lhsSign == rhsSign
    405         ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient
    406         : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient;
    407 
    408     if (lhsSign == Negative && rhsSign == Negative && !result)
    409         return Decimal(Positive, alignedOperands.exponent, 0);
    410 
    411     return static_cast<int64_t>(result) >= 0
    412         ? Decimal(lhsSign, alignedOperands.exponent, result)
    413         : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result));
    414 }
    415 
    416 Decimal Decimal::operator*(const Decimal& rhs) const
    417 {
    418     const Decimal& lhs = *this;
    419     const Sign lhsSign = lhs.sign();
    420     const Sign rhsSign = rhs.sign();
    421     const Sign resultSign = lhsSign == rhsSign ? Positive : Negative;
    422 
    423     SpecialValueHandler handler(lhs, rhs);
    424     switch (handler.handle()) {
    425     case SpecialValueHandler::BothFinite: {
    426         const uint64_t lhsCoefficient = lhs.m_data.coefficient();
    427         const uint64_t rhsCoefficient = rhs.m_data.coefficient();
    428         int resultExponent = lhs.exponent() + rhs.exponent();
    429         UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient));
    430         while (work.high()) {
    431             work /= 10;
    432             ++resultExponent;
    433         }
    434         return Decimal(resultSign, resultExponent, work.low());
    435     }
    436 
    437     case SpecialValueHandler::BothInfinity:
    438         return infinity(resultSign);
    439 
    440     case SpecialValueHandler::EitherNaN:
    441         return handler.value();
    442 
    443     case SpecialValueHandler::LHSIsInfinity:
    444         return rhs.isZero() ? nan() : infinity(resultSign);
    445 
    446     case SpecialValueHandler::RHSIsInfinity:
    447         return lhs.isZero() ? nan() : infinity(resultSign);
    448     }
    449 
    450     ASSERT_NOT_REACHED();
    451     return nan();
    452 }
    453 
    454 Decimal Decimal::operator/(const Decimal& rhs) const
    455 {
    456     const Decimal& lhs = *this;
    457     const Sign lhsSign = lhs.sign();
    458     const Sign rhsSign = rhs.sign();
    459     const Sign resultSign = lhsSign == rhsSign ? Positive : Negative;
    460 
    461     SpecialValueHandler handler(lhs, rhs);
    462     switch (handler.handle()) {
    463     case SpecialValueHandler::BothFinite:
    464         break;
    465 
    466     case SpecialValueHandler::BothInfinity:
    467         return nan();
    468 
    469     case SpecialValueHandler::EitherNaN:
    470         return handler.value();
    471 
    472     case SpecialValueHandler::LHSIsInfinity:
    473         return infinity(resultSign);
    474 
    475     case SpecialValueHandler::RHSIsInfinity:
    476         return zero(resultSign);
    477     }
    478 
    479     ASSERT(lhs.isFinite());
    480     ASSERT(rhs.isFinite());
    481 
    482     if (rhs.isZero())
    483         return lhs.isZero() ? nan() : infinity(resultSign);
    484 
    485     int resultExponent = lhs.exponent() - rhs.exponent();
    486 
    487     if (lhs.isZero())
    488         return Decimal(resultSign, resultExponent, 0);
    489 
    490     uint64_t remainder = lhs.m_data.coefficient();
    491     const uint64_t divisor = rhs.m_data.coefficient();
    492     uint64_t result = 0;
    493     while (result < MaxCoefficient / 100) {
    494         while (remainder < divisor) {
    495             remainder *= 10;
    496             result *= 10;
    497             --resultExponent;
    498         }
    499         result += remainder / divisor;
    500         remainder %= divisor;
    501         if (!remainder)
    502             break;
    503     }
    504 
    505     if (remainder > divisor / 2)
    506         ++result;
    507 
    508     return Decimal(resultSign, resultExponent, result);
    509 }
    510 
    511 bool Decimal::operator==(const Decimal& rhs) const
    512 {
    513     return m_data == rhs.m_data || compareTo(rhs).isZero();
    514 }
    515 
    516 bool Decimal::operator!=(const Decimal& rhs) const
    517 {
    518     if (m_data == rhs.m_data)
    519         return false;
    520     const Decimal result = compareTo(rhs);
    521     if (result.isNaN())
    522         return false;
    523     return !result.isZero();
    524 }
    525 
    526 bool Decimal::operator<(const Decimal& rhs) const
    527 {
    528     const Decimal result = compareTo(rhs);
    529     if (result.isNaN())
    530         return false;
    531     return !result.isZero() && result.isNegative();
    532 }
    533 
    534 bool Decimal::operator<=(const Decimal& rhs) const
    535 {
    536     if (m_data == rhs.m_data)
    537         return true;
    538     const Decimal result = compareTo(rhs);
    539     if (result.isNaN())
    540         return false;
    541     return result.isZero() || result.isNegative();
    542 }
    543 
    544 bool Decimal::operator>(const Decimal& rhs) const
    545 {
    546     const Decimal result = compareTo(rhs);
    547     if (result.isNaN())
    548         return false;
    549     return !result.isZero() && result.isPositive();
    550 }
    551 
    552 bool Decimal::operator>=(const Decimal& rhs) const
    553 {
    554     if (m_data == rhs.m_data)
    555         return true;
    556     const Decimal result = compareTo(rhs);
    557     if (result.isNaN())
    558         return false;
    559     return result.isZero() || !result.isNegative();
    560 }
    561 
    562 Decimal Decimal::abs() const
    563 {
    564     Decimal result(*this);
    565     result.m_data.setSign(Positive);
    566     return result;
    567 }
    568 
    569 Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs)
    570 {
    571     ASSERT(lhs.isFinite());
    572     ASSERT(rhs.isFinite());
    573 
    574     const int lhsExponent = lhs.exponent();
    575     const int rhsExponent = rhs.exponent();
    576     int exponent = std::min(lhsExponent, rhsExponent);
    577     uint64_t lhsCoefficient = lhs.m_data.coefficient();
    578     uint64_t rhsCoefficient = rhs.m_data.coefficient();
    579 
    580     if (lhsExponent > rhsExponent) {
    581         const int numberOfLHSDigits = countDigits(lhsCoefficient);
    582         if (numberOfLHSDigits) {
    583             const int lhsShiftAmount = lhsExponent - rhsExponent;
    584             const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision;
    585             if (overflow <= 0)
    586                 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount);
    587             else {
    588                 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow);
    589                 rhsCoefficient = scaleDown(rhsCoefficient, overflow);
    590                 exponent += overflow;
    591             }
    592         }
    593 
    594     } else if (lhsExponent < rhsExponent) {
    595         const int numberOfRHSDigits = countDigits(rhsCoefficient);
    596         if (numberOfRHSDigits) {
    597             const int rhsShiftAmount = rhsExponent - lhsExponent;
    598             const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision;
    599             if (overflow <= 0)
    600                 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount);
    601             else {
    602                 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow);
    603                 lhsCoefficient = scaleDown(lhsCoefficient, overflow);
    604                 exponent += overflow;
    605             }
    606         }
    607     }
    608 
    609     AlignedOperands alignedOperands;
    610     alignedOperands.exponent = exponent;
    611     alignedOperands.lhsCoefficient = lhsCoefficient;
    612     alignedOperands.rhsCoefficient = rhsCoefficient;
    613     return alignedOperands;
    614 }
    615 
    616 // Round toward positive infinity.
    617 // Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" here.
    618 Decimal Decimal::ceiling() const
    619 {
    620     if (isSpecial())
    621         return *this;
    622 
    623     if (exponent() >= 0)
    624         return *this;
    625 
    626     uint64_t result = m_data.coefficient();
    627     const int numberOfDigits = countDigits(result);
    628     const int numberOfDropDigits = -exponent();
    629     if (numberOfDigits < numberOfDropDigits)
    630         return isPositive() ? Decimal(1) : zero(Positive);
    631 
    632     result = scaleDown(result, numberOfDropDigits - 1);
    633     if (sign() == Positive && result % 10 > 0)
    634         result += 10;
    635     result /= 10;
    636     return Decimal(sign(), 0, result);
    637 }
    638 
    639 Decimal Decimal::compareTo(const Decimal& rhs) const
    640 {
    641     const Decimal result(*this - rhs);
    642     switch (result.m_data.formatClass()) {
    643     case EncodedData::ClassInfinity:
    644         return result.isNegative() ? Decimal(-1) : Decimal(1);
    645 
    646     case EncodedData::ClassNaN:
    647     case EncodedData::ClassNormal:
    648         return result;
    649 
    650     case EncodedData::ClassZero:
    651         return zero(Positive);
    652 
    653     default:
    654         ASSERT_NOT_REACHED();
    655         return nan();
    656     }
    657 }
    658 
    659 // Round toward negative infinity.
    660 Decimal Decimal::floor() const
    661 {
    662     if (isSpecial())
    663         return *this;
    664 
    665     if (exponent() >= 0)
    666         return *this;
    667 
    668     uint64_t result = m_data.coefficient();
    669     const int numberOfDigits = countDigits(result);
    670     const int numberOfDropDigits = -exponent();
    671     if (numberOfDigits < numberOfDropDigits)
    672         return isPositive() ? zero(Positive) : Decimal(-1);
    673 
    674     result = scaleDown(result, numberOfDropDigits - 1);
    675     if (isNegative() && result % 10 > 0)
    676         result += 10;
    677     result /= 10;
    678     return Decimal(sign(), 0, result);
    679 }
    680 
    681 Decimal Decimal::fromDouble(double doubleValue)
    682 {
    683     if (std::isfinite(doubleValue))
    684         return fromString(String::numberToStringECMAScript(doubleValue));
    685 
    686     if (std::isinf(doubleValue))
    687         return infinity(doubleValue < 0 ? Negative : Positive);
    688 
    689     return nan();
    690 }
    691 
    692 Decimal Decimal::fromString(const String& str)
    693 {
    694     int exponent = 0;
    695     Sign exponentSign = Positive;
    696     int numberOfDigits = 0;
    697     int numberOfDigitsAfterDot = 0;
    698     int numberOfExtraDigits = 0;
    699     Sign sign = Positive;
    700 
    701     enum {
    702         StateDigit,
    703         StateDot,
    704         StateDotDigit,
    705         StateE,
    706         StateEDigit,
    707         StateESign,
    708         StateSign,
    709         StateStart,
    710         StateZero,
    711     } state = StateStart;
    712 
    713 #define HandleCharAndBreak(expected, nextState) \
    714     if (ch == expected) { \
    715         state = nextState; \
    716         break; \
    717     }
    718 
    719 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
    720     if (ch == expected1 || ch == expected2) { \
    721         state = nextState; \
    722         break; \
    723     }
    724 
    725     uint64_t accumulator = 0;
    726     for (unsigned index = 0; index < str.length(); ++index) {
    727         const int ch = str[index];
    728         switch (state) {
    729         case StateDigit:
    730             if (ch >= '0' && ch <= '9') {
    731                 if (numberOfDigits < Precision) {
    732                     ++numberOfDigits;
    733                     accumulator *= 10;
    734                     accumulator += ch - '0';
    735                 } else
    736                     ++numberOfExtraDigits;
    737                 break;
    738             }
    739 
    740             HandleCharAndBreak('.', StateDot);
    741             HandleTwoCharsAndBreak('E', 'e', StateE);
    742             return nan();
    743 
    744         case StateDot:
    745             if (ch >= '0' && ch <= '9') {
    746                 if (numberOfDigits < Precision) {
    747                     ++numberOfDigits;
    748                     ++numberOfDigitsAfterDot;
    749                     accumulator *= 10;
    750                     accumulator += ch - '0';
    751                 }
    752                 state = StateDotDigit;
    753                 break;
    754             }
    755 
    756         case StateDotDigit:
    757             if (ch >= '0' && ch <= '9') {
    758                 if (numberOfDigits < Precision) {
    759                     ++numberOfDigits;
    760                     ++numberOfDigitsAfterDot;
    761                     accumulator *= 10;
    762                     accumulator += ch - '0';
    763                 }
    764                 break;
    765             }
    766 
    767             HandleTwoCharsAndBreak('E', 'e', StateE);
    768             return nan();
    769 
    770         case StateE:
    771             if (ch == '+') {
    772                 exponentSign = Positive;
    773                 state = StateESign;
    774                 break;
    775             }
    776 
    777             if (ch == '-') {
    778                 exponentSign = Negative;
    779                 state = StateESign;
    780                 break;
    781             }
    782 
    783             if (ch >= '0' && ch <= '9') {
    784                 exponent = ch - '0';
    785                 state = StateEDigit;
    786                 break;
    787             }
    788 
    789             return nan();
    790 
    791         case StateEDigit:
    792             if (ch >= '0' && ch <= '9') {
    793                 exponent *= 10;
    794                 exponent += ch - '0';
    795                 if (exponent > ExponentMax + Precision) {
    796                     if (accumulator)
    797                         return exponentSign == Negative ? zero(Positive) : infinity(sign);
    798                     return zero(sign);
    799                 }
    800                 state = StateEDigit;
    801                 break;
    802             }
    803 
    804             return nan();
    805 
    806         case StateESign:
    807             if (ch >= '0' && ch <= '9') {
    808                 exponent = ch - '0';
    809                 state = StateEDigit;
    810                 break;
    811             }
    812 
    813             return nan();
    814 
    815         case StateSign:
    816             if (ch >= '1' && ch <= '9') {
    817                 accumulator = ch - '0';
    818                 numberOfDigits = 1;
    819                 state = StateDigit;
    820                 break;
    821             }
    822 
    823             HandleCharAndBreak('0', StateZero);
    824             return nan();
    825 
    826         case StateStart:
    827             if (ch >= '1' && ch <= '9') {
    828                 accumulator = ch - '0';
    829                 numberOfDigits = 1;
    830                 state = StateDigit;
    831                 break;
    832             }
    833 
    834             if (ch == '-') {
    835                 sign = Negative;
    836                 state = StateSign;
    837                 break;
    838             }
    839 
    840             if (ch == '+') {
    841                 sign = Positive;
    842                 state = StateSign;
    843                 break;
    844             }
    845 
    846             HandleCharAndBreak('0', StateZero);
    847             HandleCharAndBreak('.', StateDot);
    848             return nan();
    849 
    850         case StateZero:
    851             if (ch == '0')
    852                 break;
    853 
    854             if (ch >= '1' && ch <= '9') {
    855                 accumulator = ch - '0';
    856                 numberOfDigits = 1;
    857                 state = StateDigit;
    858                 break;
    859             }
    860 
    861             HandleCharAndBreak('.', StateDot);
    862             HandleTwoCharsAndBreak('E', 'e', StateE);
    863             return nan();
    864 
    865         default:
    866             ASSERT_NOT_REACHED();
    867             return nan();
    868         }
    869     }
    870 
    871     if (state == StateZero)
    872         return zero(sign);
    873 
    874     if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
    875         int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
    876         if (resultExponent < ExponentMin)
    877             return zero(Positive);
    878 
    879         const int overflow = resultExponent - ExponentMax + 1;
    880         if (overflow > 0) {
    881             if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision)
    882                 return infinity(sign);
    883             accumulator = scaleUp(accumulator, overflow);
    884             resultExponent -= overflow;
    885         }
    886 
    887         return Decimal(sign, resultExponent, accumulator);
    888     }
    889 
    890     return nan();
    891 }
    892 
    893 Decimal Decimal::infinity(const Sign sign)
    894 {
    895     return Decimal(EncodedData(sign, EncodedData::ClassInfinity));
    896 }
    897 
    898 Decimal Decimal::nan()
    899 {
    900     return Decimal(EncodedData(Positive, EncodedData::ClassNaN));
    901 }
    902 
    903 Decimal Decimal::remainder(const Decimal& rhs) const
    904 {
    905     const Decimal quotient = *this / rhs;
    906     return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceiling() : quotient.floor()) * rhs;
    907 }
    908 
    909 Decimal Decimal::round() const
    910 {
    911     if (isSpecial())
    912         return *this;
    913 
    914     if (exponent() >= 0)
    915         return *this;
    916 
    917     uint64_t result = m_data.coefficient();
    918     const int numberOfDigits = countDigits(result);
    919     const int numberOfDropDigits = -exponent();
    920     if (numberOfDigits < numberOfDropDigits)
    921         return zero(Positive);
    922 
    923     result = scaleDown(result, numberOfDropDigits - 1);
    924     if (result % 10 >= 5)
    925         result += 10;
    926     result /= 10;
    927     return Decimal(sign(), 0, result);
    928 }
    929 
    930 double Decimal::toDouble() const
    931 {
    932     if (isFinite()) {
    933         bool valid;
    934         const double doubleValue = toString().toDouble(&valid);
    935         return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN();
    936     }
    937 
    938     if (isInfinity())
    939         return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
    940 
    941     return std::numeric_limits<double>::quiet_NaN();
    942 }
    943 
    944 String Decimal::toString() const
    945 {
    946     switch (m_data.formatClass()) {
    947     case EncodedData::ClassInfinity:
    948         return sign() ? "-Infinity" : "Infinity";
    949 
    950     case EncodedData::ClassNaN:
    951         return "NaN";
    952 
    953     case EncodedData::ClassNormal:
    954     case EncodedData::ClassZero:
    955         break;
    956 
    957     default:
    958         ASSERT_NOT_REACHED();
    959         return "";
    960     }
    961 
    962     StringBuilder builder;
    963     if (sign())
    964         builder.append('-');
    965 
    966     int originalExponent = exponent();
    967     uint64_t coefficient = m_data.coefficient();
    968 
    969     if (originalExponent < 0) {
    970         const int maxDigits = DBL_DIG;
    971         uint64_t lastDigit = 0;
    972         while (countDigits(coefficient) > maxDigits) {
    973             lastDigit = coefficient % 10;
    974             coefficient /= 10;
    975             ++originalExponent;
    976         }
    977 
    978         if (lastDigit >= 5)
    979             ++coefficient;
    980 
    981         while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
    982             coefficient /= 10;
    983             ++originalExponent;
    984         }
    985     }
    986 
    987     const String digits = String::number(coefficient);
    988     int coefficientLength = static_cast<int>(digits.length());
    989     const int adjustedExponent = originalExponent + coefficientLength - 1;
    990     if (originalExponent <= 0 && adjustedExponent >= -6) {
    991         if (!originalExponent) {
    992             builder.append(digits);
    993             return builder.toString();
    994         }
    995 
    996         if (adjustedExponent >= 0) {
    997             for (int i = 0; i < coefficientLength; ++i) {
    998                 builder.append(digits[i]);
    999                 if (i == adjustedExponent)
   1000                     builder.append('.');
   1001             }
   1002             return builder.toString();
   1003         }
   1004 
   1005         builder.appendLiteral("0.");
   1006         for (int i = adjustedExponent + 1; i < 0; ++i)
   1007             builder.append('0');
   1008 
   1009         builder.append(digits);
   1010 
   1011     } else {
   1012         builder.append(digits[0]);
   1013         while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0')
   1014             --coefficientLength;
   1015         if (coefficientLength >= 2) {
   1016             builder.append('.');
   1017             for (int i = 1; i < coefficientLength; ++i)
   1018                 builder.append(digits[i]);
   1019         }
   1020 
   1021         if (adjustedExponent) {
   1022             builder.append(adjustedExponent < 0 ? "e" : "e+");
   1023             builder.appendNumber(adjustedExponent);
   1024         }
   1025     }
   1026     return builder.toString();
   1027 }
   1028 
   1029 Decimal Decimal::zero(Sign sign)
   1030 {
   1031     return Decimal(EncodedData(sign, EncodedData::ClassZero));
   1032 }
   1033 
   1034 } // namespace WebCore
   1035