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