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 blink {
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
SpecialValueHandler(const Decimal & lhs,const Decimal & rhs)79 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs)
80 : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown)
81 {
82 }
83
handle()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
value() const111 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:
UInt128(uint64_t low,uint64_t high)128 UInt128(uint64_t low, uint64_t high)
129 : m_high(high), m_low(low)
130 {
131 }
132
133 UInt128& operator/=(uint32_t);
134
high() const135 uint64_t high() const { return m_high; }
low() const136 uint64_t low() const { return m_low; }
137
multiply(uint64_t u,uint64_t v)138 static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); }
139
140 private:
highUInt32(uint64_t x)141 static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); }
lowUInt32(uint64_t x)142 static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); }
makeUInt64(uint32_t low,uint32_t high)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
operator /=(const uint32_t divisor)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.
multiplyHigh(uint64_t u,uint64_t v)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
countDigits(uint64_t x)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
scaleDown(uint64_t x,int n)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
scaleUp(uint64_t x,int n)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
EncodedData(Sign sign,FormatClass formatClass)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
EncodedData(Sign sign,int exponent,uint64_t coefficient)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
operator ==(const EncodedData & another) const270 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
Decimal(int32_t i32)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
Decimal(Sign sign,int exponent,uint64_t coefficient)283 Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
284 : m_data(sign, exponent, coefficient)
285 {
286 }
287
Decimal(const EncodedData & data)288 Decimal::Decimal(const EncodedData& data)
289 : m_data(data)
290 {
291 }
292
Decimal(const Decimal & other)293 Decimal::Decimal(const Decimal& other)
294 : m_data(other.m_data)
295 {
296 }
297
operator =(const Decimal & other)298 Decimal& Decimal::operator=(const Decimal& other)
299 {
300 m_data = other.m_data;
301 return *this;
302 }
303
operator +=(const Decimal & other)304 Decimal& Decimal::operator+=(const Decimal& other)
305 {
306 m_data = (*this + other).m_data;
307 return *this;
308 }
309
operator -=(const Decimal & other)310 Decimal& Decimal::operator-=(const Decimal& other)
311 {
312 m_data = (*this - other).m_data;
313 return *this;
314 }
315
operator *=(const Decimal & other)316 Decimal& Decimal::operator*=(const Decimal& other)
317 {
318 m_data = (*this * other).m_data;
319 return *this;
320 }
321
operator /=(const Decimal & other)322 Decimal& Decimal::operator/=(const Decimal& other)
323 {
324 m_data = (*this / other).m_data;
325 return *this;
326 }
327
operator -() const328 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
operator +(const Decimal & rhs) const338 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
operator -(const Decimal & rhs) const376 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
operator *(const Decimal & rhs) const414 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
operator /(const Decimal & rhs) const452 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
operator ==(const Decimal & rhs) const509 bool Decimal::operator==(const Decimal& rhs) const
510 {
511 return m_data == rhs.m_data || compareTo(rhs).isZero();
512 }
513
operator !=(const Decimal & rhs) const514 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
operator <(const Decimal & rhs) const524 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
operator <=(const Decimal & rhs) const532 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
operator >(const Decimal & rhs) const542 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
operator >=(const Decimal & rhs) const550 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
abs() const560 Decimal Decimal::abs() const
561 {
562 Decimal result(*this);
563 result.m_data.setSign(Positive);
564 return result;
565 }
566
alignOperands(const Decimal & lhs,const Decimal & rhs)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
isMultiplePowersOfTen(uint64_t coefficient,int n)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.
ceiling() const621 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
compareTo(const Decimal & rhs) const641 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.
floor() const662 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
fromDouble(double doubleValue)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
fromString(const String & str)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
infinity(const Sign sign)885 Decimal Decimal::infinity(const Sign sign)
886 {
887 return Decimal(EncodedData(sign, EncodedData::ClassInfinity));
888 }
889
nan()890 Decimal Decimal::nan()
891 {
892 return Decimal(EncodedData(Positive, EncodedData::ClassNaN));
893 }
894
remainder(const Decimal & rhs) const895 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
round() const901 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
toDouble() const922 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
toString() const936 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
zero(Sign sign)1021 Decimal Decimal::zero(Sign sign)
1022 {
1023 return Decimal(EncodedData(sign, EncodedData::ClassZero));
1024 }
1025
1026 } // namespace blink
1027