Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / Decimal.cpp
blob97013153dc5eabf11bde42d383cb1bb0b03d6eda
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
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.
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.
31 #include "config.h"
32 #include "platform/Decimal.h"
34 #include "wtf/MathExtras.h"
35 #include "wtf/Noncopyable.h"
36 #include "wtf/text/StringBuilder.h"
38 #include <algorithm>
39 #include <float.h>
41 namespace blink {
43 namespace DecimalPrivate {
45 static int const ExponentMax = 1023;
46 static int const ExponentMin = -1023;
47 static int const Precision = 18;
49 static const uint64_t MaxCoefficient = UINT64_C(0xDE0B6B3A763FFFF); // 999999999999999999 == 18 9's
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,
63 SpecialValueHandler(const Decimal& lhs, const Decimal& rhs);
64 HandleResult handle();
65 Decimal value() const;
67 private:
68 enum Result {
69 ResultIsLHS,
70 ResultIsRHS,
71 ResultIsUnknown,
74 const Decimal& m_lhs;
75 const Decimal& m_rhs;
76 Result m_result;
79 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs)
80 : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown)
84 SpecialValueHandler::HandleResult SpecialValueHandler::handle()
86 if (m_lhs.isFinite() && m_rhs.isFinite())
87 return BothFinite;
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;
96 if (rhsClass == Decimal::EncodedData::ClassNaN) {
97 m_result = ResultIsRHS;
98 return EitherNaN;
101 if (lhsClass == Decimal::EncodedData::ClassInfinity)
102 return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity;
104 if (rhsClass == Decimal::EncodedData::ClassInfinity)
105 return RHSIsInfinity;
107 ASSERT_NOT_REACHED();
108 return BothFinite;
111 Decimal SpecialValueHandler::value() const
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;
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)
133 UInt128& operator/=(uint32_t);
135 uint64_t high() const { return m_high; }
136 uint64_t low() const { return m_low; }
138 static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); }
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); }
145 static uint64_t multiplyHigh(uint64_t, uint64_t);
147 uint64_t m_high;
148 uint64_t m_low;
151 UInt128& UInt128::operator/=(const uint32_t divisor)
153 ASSERT(divisor);
155 if (!m_high) {
156 m_low /= divisor;
157 return *this;
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);
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);
173 m_low = makeUInt64(quotient[0], quotient[1]);
174 m_high = makeUInt64(quotient[2], quotient[3]);
175 return *this;
178 // Returns high 64bit of 128bit product.
179 uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v)
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));
189 static int countDigits(uint64_t x)
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;
197 return numberOfDigits;
200 static uint64_t scaleDown(uint64_t x, int n)
202 ASSERT(n >= 0);
203 while (n > 0 && x) {
204 x /= 10;
205 --n;
207 return x;
210 static uint64_t scaleUp(uint64_t x, int n)
212 ASSERT(n >= 0);
213 ASSERT(n < Precision);
215 uint64_t y = 1;
216 uint64_t z = 10;
217 for (;;) {
218 if (n & 1)
219 y = y * z;
221 n >>= 1;
222 if (!n)
223 return x * y;
225 z = z * z;
229 } // namespace DecimalPrivate
231 using namespace DecimalPrivate;
233 Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass)
234 : m_coefficient(0)
235 , m_exponent(0)
236 , m_formatClass(formatClass)
237 , m_sign(sign)
241 Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient)
242 : m_formatClass(coefficient ? ClassNormal : ClassZero)
243 , m_sign(sign)
245 if (exponent >= ExponentMin && exponent <= ExponentMax) {
246 while (coefficient > MaxCoefficient) {
247 coefficient /= 10;
248 ++exponent;
252 if (exponent > ExponentMax) {
253 m_coefficient = 0;
254 m_exponent = 0;
255 m_formatClass = ClassInfinity;
256 return;
259 if (exponent < ExponentMin) {
260 m_coefficient = 0;
261 m_exponent = 0;
262 m_formatClass = ClassZero;
263 return;
266 m_coefficient = coefficient;
267 m_exponent = static_cast<int16_t>(exponent);
270 bool Decimal::EncodedData::operator==(const EncodedData& another) const
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;
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))
283 Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
284 : m_data(sign, exponent, coefficient)
288 Decimal::Decimal(const EncodedData& data)
289 : m_data(data)
293 Decimal::Decimal(const Decimal& other)
294 : m_data(other.m_data)
298 Decimal& Decimal::operator=(const Decimal& other)
300 m_data = other.m_data;
301 return *this;
304 Decimal& Decimal::operator+=(const Decimal& other)
306 m_data = (*this + other).m_data;
307 return *this;
310 Decimal& Decimal::operator-=(const Decimal& other)
312 m_data = (*this - other).m_data;
313 return *this;
316 Decimal& Decimal::operator*=(const Decimal& other)
318 m_data = (*this * other).m_data;
319 return *this;
322 Decimal& Decimal::operator/=(const Decimal& other)
324 m_data = (*this / other).m_data;
325 return *this;
328 Decimal Decimal::operator-() const
330 if (isNaN())
331 return *this;
333 Decimal result(*this);
334 result.m_data.setSign(invertSign(m_data.sign()));
335 return result;
338 Decimal Decimal::operator+(const Decimal& rhs) const
340 const Decimal& lhs = *this;
341 const Sign lhsSign = lhs.sign();
342 const Sign rhsSign = rhs.sign();
344 SpecialValueHandler handler(lhs, rhs);
345 switch (handler.handle()) {
346 case SpecialValueHandler::BothFinite:
347 break;
349 case SpecialValueHandler::BothInfinity:
350 return lhsSign == rhsSign ? lhs : nan();
352 case SpecialValueHandler::EitherNaN:
353 return handler.value();
355 case SpecialValueHandler::LHSIsInfinity:
356 return lhs;
358 case SpecialValueHandler::RHSIsInfinity:
359 return rhs;
362 const AlignedOperands alignedOperands = alignOperands(lhs, rhs);
364 const uint64_t result = lhsSign == rhsSign
365 ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient
366 : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient;
368 if (lhsSign == Negative && rhsSign == Positive && !result)
369 return Decimal(Positive, alignedOperands.exponent, 0);
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));
376 Decimal Decimal::operator-(const Decimal& rhs) const
378 const Decimal& lhs = *this;
379 const Sign lhsSign = lhs.sign();
380 const Sign rhsSign = rhs.sign();
382 SpecialValueHandler handler(lhs, rhs);
383 switch (handler.handle()) {
384 case SpecialValueHandler::BothFinite:
385 break;
387 case SpecialValueHandler::BothInfinity:
388 return lhsSign == rhsSign ? nan() : lhs;
390 case SpecialValueHandler::EitherNaN:
391 return handler.value();
393 case SpecialValueHandler::LHSIsInfinity:
394 return lhs;
396 case SpecialValueHandler::RHSIsInfinity:
397 return infinity(invertSign(rhsSign));
400 const AlignedOperands alignedOperands = alignOperands(lhs, rhs);
402 const uint64_t result = lhsSign == rhsSign
403 ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient
404 : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient;
406 if (lhsSign == Negative && rhsSign == Negative && !result)
407 return Decimal(Positive, alignedOperands.exponent, 0);
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));
414 Decimal Decimal::operator*(const Decimal& rhs) const
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;
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;
432 return Decimal(resultSign, resultExponent, work.low());
435 case SpecialValueHandler::BothInfinity:
436 return infinity(resultSign);
438 case SpecialValueHandler::EitherNaN:
439 return handler.value();
441 case SpecialValueHandler::LHSIsInfinity:
442 return rhs.isZero() ? nan() : infinity(resultSign);
444 case SpecialValueHandler::RHSIsInfinity:
445 return lhs.isZero() ? nan() : infinity(resultSign);
448 ASSERT_NOT_REACHED();
449 return nan();
452 Decimal Decimal::operator/(const Decimal& rhs) const
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;
459 SpecialValueHandler handler(lhs, rhs);
460 switch (handler.handle()) {
461 case SpecialValueHandler::BothFinite:
462 break;
464 case SpecialValueHandler::BothInfinity:
465 return nan();
467 case SpecialValueHandler::EitherNaN:
468 return handler.value();
470 case SpecialValueHandler::LHSIsInfinity:
471 return infinity(resultSign);
473 case SpecialValueHandler::RHSIsInfinity:
474 return zero(resultSign);
477 ASSERT(lhs.isFinite());
478 ASSERT(rhs.isFinite());
480 if (rhs.isZero())
481 return lhs.isZero() ? nan() : infinity(resultSign);
483 int resultExponent = lhs.exponent() - rhs.exponent();
485 if (lhs.isZero())
486 return Decimal(resultSign, resultExponent, 0);
488 uint64_t remainder = lhs.m_data.coefficient();
489 const uint64_t divisor = rhs.m_data.coefficient();
490 uint64_t result = 0;
491 for (;;) {
492 while (remainder < divisor && result < MaxCoefficient / 10) {
493 remainder *= 10;
494 result *= 10;
495 --resultExponent;
497 if (remainder < divisor)
498 break;
499 uint64_t quotient = remainder / divisor;
500 if (result > MaxCoefficient - quotient)
501 break;
502 result += quotient;
503 remainder %= divisor;
504 if (!remainder)
505 break;
508 if (remainder > divisor / 2)
509 ++result;
511 return Decimal(resultSign, resultExponent, result);
514 bool Decimal::operator==(const Decimal& rhs) const
516 return m_data == rhs.m_data || compareTo(rhs).isZero();
519 bool Decimal::operator!=(const Decimal& rhs) const
521 if (m_data == rhs.m_data)
522 return false;
523 const Decimal result = compareTo(rhs);
524 if (result.isNaN())
525 return false;
526 return !result.isZero();
529 bool Decimal::operator<(const Decimal& rhs) const
531 const Decimal result = compareTo(rhs);
532 if (result.isNaN())
533 return false;
534 return !result.isZero() && result.isNegative();
537 bool Decimal::operator<=(const Decimal& rhs) const
539 if (m_data == rhs.m_data)
540 return true;
541 const Decimal result = compareTo(rhs);
542 if (result.isNaN())
543 return false;
544 return result.isZero() || result.isNegative();
547 bool Decimal::operator>(const Decimal& rhs) const
549 const Decimal result = compareTo(rhs);
550 if (result.isNaN())
551 return false;
552 return !result.isZero() && result.isPositive();
555 bool Decimal::operator>=(const Decimal& rhs) const
557 if (m_data == rhs.m_data)
558 return true;
559 const Decimal result = compareTo(rhs);
560 if (result.isNaN())
561 return false;
562 return result.isZero() || !result.isNegative();
565 Decimal Decimal::abs() const
567 Decimal result(*this);
568 result.m_data.setSign(Positive);
569 return result;
572 Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs)
574 ASSERT(lhs.isFinite());
575 ASSERT(rhs.isFinite());
577 const int lhsExponent = lhs.exponent();
578 const int rhsExponent = rhs.exponent();
579 int exponent = std::min(lhsExponent, rhsExponent);
580 uint64_t lhsCoefficient = lhs.m_data.coefficient();
581 uint64_t rhsCoefficient = rhs.m_data.coefficient();
583 if (lhsExponent > rhsExponent) {
584 const int numberOfLHSDigits = countDigits(lhsCoefficient);
585 if (numberOfLHSDigits) {
586 const int lhsShiftAmount = lhsExponent - rhsExponent;
587 const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision;
588 if (overflow <= 0) {
589 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount);
590 } else {
591 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow);
592 rhsCoefficient = scaleDown(rhsCoefficient, overflow);
593 exponent += overflow;
597 } else if (lhsExponent < rhsExponent) {
598 const int numberOfRHSDigits = countDigits(rhsCoefficient);
599 if (numberOfRHSDigits) {
600 const int rhsShiftAmount = rhsExponent - lhsExponent;
601 const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision;
602 if (overflow <= 0) {
603 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount);
604 } else {
605 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow);
606 lhsCoefficient = scaleDown(lhsCoefficient, overflow);
607 exponent += overflow;
612 AlignedOperands alignedOperands;
613 alignedOperands.exponent = exponent;
614 alignedOperands.lhsCoefficient = lhsCoefficient;
615 alignedOperands.rhsCoefficient = rhsCoefficient;
616 return alignedOperands;
619 static bool isMultiplePowersOfTen(uint64_t coefficient, int n)
621 return !coefficient || !(coefficient % scaleUp(1, n));
624 // Round toward positive infinity.
625 Decimal Decimal::ceil() const
627 if (isSpecial())
628 return *this;
630 if (exponent() >= 0)
631 return *this;
633 uint64_t result = m_data.coefficient();
634 const int numberOfDigits = countDigits(result);
635 const int numberOfDropDigits = -exponent();
636 if (numberOfDigits <= numberOfDropDigits)
637 return isPositive() ? Decimal(1) : zero(Positive);
639 result = scaleDown(result, numberOfDropDigits);
640 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits))
641 ++result;
642 return Decimal(sign(), 0, result);
645 Decimal Decimal::compareTo(const Decimal& rhs) const
647 const Decimal result(*this - rhs);
648 switch (result.m_data.formatClass()) {
649 case EncodedData::ClassInfinity:
650 return result.isNegative() ? Decimal(-1) : Decimal(1);
652 case EncodedData::ClassNaN:
653 case EncodedData::ClassNormal:
654 return result;
656 case EncodedData::ClassZero:
657 return zero(Positive);
659 default:
660 ASSERT_NOT_REACHED();
661 return nan();
665 // Round toward negative infinity.
666 Decimal Decimal::floor() const
668 if (isSpecial())
669 return *this;
671 if (exponent() >= 0)
672 return *this;
674 uint64_t result = m_data.coefficient();
675 const int numberOfDigits = countDigits(result);
676 const int numberOfDropDigits = -exponent();
677 if (numberOfDigits < numberOfDropDigits)
678 return isPositive() ? zero(Positive) : Decimal(-1);
680 result = scaleDown(result, numberOfDropDigits);
681 if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits))
682 ++result;
683 return Decimal(sign(), 0, result);
686 Decimal Decimal::fromDouble(double doubleValue)
688 if (std::isfinite(doubleValue))
689 return fromString(String::numberToStringECMAScript(doubleValue));
691 if (std::isinf(doubleValue))
692 return infinity(doubleValue < 0 ? Negative : Positive);
694 return nan();
697 Decimal Decimal::fromString(const String& str)
699 int exponent = 0;
700 Sign exponentSign = Positive;
701 int numberOfDigits = 0;
702 int numberOfDigitsAfterDot = 0;
703 int numberOfExtraDigits = 0;
704 Sign sign = Positive;
706 enum {
707 StateDigit,
708 StateDot,
709 StateDotDigit,
710 StateE,
711 StateEDigit,
712 StateESign,
713 StateSign,
714 StateStart,
715 StateZero,
716 } state = StateStart;
718 #define HandleCharAndBreak(expected, nextState) \
719 if (ch == expected) { \
720 state = nextState; \
721 break; \
724 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
725 if (ch == expected1 || ch == expected2) { \
726 state = nextState; \
727 break; \
730 uint64_t accumulator = 0;
731 for (unsigned index = 0; index < str.length(); ++index) {
732 const int ch = str[index];
733 switch (state) {
734 case StateDigit:
735 if (ch >= '0' && ch <= '9') {
736 if (numberOfDigits < Precision) {
737 ++numberOfDigits;
738 accumulator *= 10;
739 accumulator += ch - '0';
740 } else {
741 ++numberOfExtraDigits;
743 break;
746 HandleCharAndBreak('.', StateDot);
747 HandleTwoCharsAndBreak('E', 'e', StateE);
748 return nan();
750 case StateDot:
751 case StateDotDigit:
752 if (ch >= '0' && ch <= '9') {
753 if (numberOfDigits < Precision) {
754 ++numberOfDigits;
755 ++numberOfDigitsAfterDot;
756 accumulator *= 10;
757 accumulator += ch - '0';
759 state = StateDotDigit;
760 break;
763 HandleTwoCharsAndBreak('E', 'e', StateE);
764 return nan();
766 case StateE:
767 if (ch == '+') {
768 exponentSign = Positive;
769 state = StateESign;
770 break;
773 if (ch == '-') {
774 exponentSign = Negative;
775 state = StateESign;
776 break;
779 if (ch >= '0' && ch <= '9') {
780 exponent = ch - '0';
781 state = StateEDigit;
782 break;
785 return nan();
787 case StateEDigit:
788 if (ch >= '0' && ch <= '9') {
789 exponent *= 10;
790 exponent += ch - '0';
791 if (exponent > ExponentMax + Precision) {
792 if (accumulator)
793 return exponentSign == Negative ? zero(Positive) : infinity(sign);
794 return zero(sign);
796 state = StateEDigit;
797 break;
800 return nan();
802 case StateESign:
803 if (ch >= '0' && ch <= '9') {
804 exponent = ch - '0';
805 state = StateEDigit;
806 break;
809 return nan();
811 case StateSign:
812 if (ch >= '1' && ch <= '9') {
813 accumulator = ch - '0';
814 numberOfDigits = 1;
815 state = StateDigit;
816 break;
819 HandleCharAndBreak('0', StateZero);
820 return nan();
822 case StateStart:
823 if (ch >= '1' && ch <= '9') {
824 accumulator = ch - '0';
825 numberOfDigits = 1;
826 state = StateDigit;
827 break;
830 if (ch == '-') {
831 sign = Negative;
832 state = StateSign;
833 break;
836 if (ch == '+') {
837 sign = Positive;
838 state = StateSign;
839 break;
842 HandleCharAndBreak('0', StateZero);
843 HandleCharAndBreak('.', StateDot);
844 return nan();
846 case StateZero:
847 if (ch == '0')
848 break;
850 if (ch >= '1' && ch <= '9') {
851 accumulator = ch - '0';
852 numberOfDigits = 1;
853 state = StateDigit;
854 break;
857 HandleCharAndBreak('.', StateDot);
858 HandleTwoCharsAndBreak('E', 'e', StateE);
859 return nan();
861 default:
862 ASSERT_NOT_REACHED();
863 return nan();
867 if (state == StateZero)
868 return zero(sign);
870 if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
871 int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
872 if (resultExponent < ExponentMin)
873 return zero(Positive);
875 const int overflow = resultExponent - ExponentMax + 1;
876 if (overflow > 0) {
877 if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision)
878 return infinity(sign);
879 accumulator = scaleUp(accumulator, overflow);
880 resultExponent -= overflow;
883 return Decimal(sign, resultExponent, accumulator);
886 return nan();
889 Decimal Decimal::infinity(const Sign sign)
891 return Decimal(EncodedData(sign, EncodedData::ClassInfinity));
894 Decimal Decimal::nan()
896 return Decimal(EncodedData(Positive, EncodedData::ClassNaN));
899 Decimal Decimal::remainder(const Decimal& rhs) const
901 const Decimal quotient = *this / rhs;
902 return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceil() : quotient.floor()) * rhs;
905 Decimal Decimal::round() const
907 if (isSpecial())
908 return *this;
910 if (exponent() >= 0)
911 return *this;
913 uint64_t result = m_data.coefficient();
914 const int numberOfDigits = countDigits(result);
915 const int numberOfDropDigits = -exponent();
916 if (numberOfDigits < numberOfDropDigits)
917 return zero(Positive);
919 result = scaleDown(result, numberOfDropDigits - 1);
920 if (result % 10 >= 5)
921 result += 10;
922 result /= 10;
923 return Decimal(sign(), 0, result);
926 double Decimal::toDouble() const
928 if (isFinite()) {
929 bool valid;
930 const double doubleValue = toString().toDouble(&valid);
931 return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN();
934 if (isInfinity())
935 return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
937 return std::numeric_limits<double>::quiet_NaN();
940 String Decimal::toString() const
942 switch (m_data.formatClass()) {
943 case EncodedData::ClassInfinity:
944 return sign() ? "-Infinity" : "Infinity";
946 case EncodedData::ClassNaN:
947 return "NaN";
949 case EncodedData::ClassNormal:
950 case EncodedData::ClassZero:
951 break;
953 default:
954 ASSERT_NOT_REACHED();
955 return "";
958 StringBuilder builder;
959 if (sign())
960 builder.append('-');
962 int originalExponent = exponent();
963 uint64_t coefficient = m_data.coefficient();
965 if (originalExponent < 0) {
966 const int maxDigits = DBL_DIG;
967 uint64_t lastDigit = 0;
968 while (countDigits(coefficient) > maxDigits) {
969 lastDigit = coefficient % 10;
970 coefficient /= 10;
971 ++originalExponent;
974 if (lastDigit >= 5)
975 ++coefficient;
977 while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
978 coefficient /= 10;
979 ++originalExponent;
983 const String digits = String::number(coefficient);
984 int coefficientLength = static_cast<int>(digits.length());
985 const int adjustedExponent = originalExponent + coefficientLength - 1;
986 if (originalExponent <= 0 && adjustedExponent >= -6) {
987 if (!originalExponent) {
988 builder.append(digits);
989 return builder.toString();
992 if (adjustedExponent >= 0) {
993 for (int i = 0; i < coefficientLength; ++i) {
994 builder.append(digits[i]);
995 if (i == adjustedExponent)
996 builder.append('.');
998 return builder.toString();
1001 builder.appendLiteral("0.");
1002 for (int i = adjustedExponent + 1; i < 0; ++i)
1003 builder.append('0');
1005 builder.append(digits);
1007 } else {
1008 builder.append(digits[0]);
1009 while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0')
1010 --coefficientLength;
1011 if (coefficientLength >= 2) {
1012 builder.append('.');
1013 for (int i = 1; i < coefficientLength; ++i)
1014 builder.append(digits[i]);
1017 if (adjustedExponent) {
1018 builder.append(adjustedExponent < 0 ? "e" : "e+");
1019 builder.appendNumber(adjustedExponent);
1022 return builder.toString();
1025 Decimal Decimal::zero(Sign sign)
1027 return Decimal(EncodedData(sign, EncodedData::ClassZero));
1030 } // namespace blink