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