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