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 "third_party/blink/renderer/platform/wtf/decimal.h"
32 
33 #include <algorithm>
34 #include <cfloat>
35 
36 #include "base/macros.h"
37 #include "base/notreached.h"
38 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
39 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
40 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
41 
42 namespace blink {
43 
44 namespace {
45 
46 constexpr int kExponentMax = 1023;
47 constexpr int kExponentMin = -1023;
48 constexpr int kPrecision = 18;
49 
50 constexpr uint64_t kMaxCoefficient =
51     UINT64_C(0xDE0B6B3A763FFFF);  // 999999999999999999 == 18 9's
52 
53 // This class handles Decimal special values.
54 class SpecialValueHandler {
55   STACK_ALLOCATED();
56 
57  public:
58   enum HandleResult {
59     kBothFinite,
60     kBothInfinity,
61     kEitherNaN,
62     kLHSIsInfinity,
63     kRHSIsInfinity,
64   };
65 
66   SpecialValueHandler(const Decimal& lhs, const Decimal& rhs);
67   HandleResult Handle();
68   Decimal Value() const;
69 
70  private:
71   enum Result {
72     kResultIsLHS,
73     kResultIsRHS,
74     kResultIsUnknown,
75   };
76 
77   const Decimal& lhs_;
78   const Decimal& rhs_;
79   Result result_ = kResultIsUnknown;
80 
81   DISALLOW_COPY_AND_ASSIGN(SpecialValueHandler);
82 };
83 
SpecialValueHandler(const Decimal & lhs,const Decimal & rhs)84 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs)
85     : lhs_(lhs), rhs_(rhs) {}
86 
Handle()87 SpecialValueHandler::HandleResult SpecialValueHandler::Handle() {
88   if (lhs_.IsFinite() && rhs_.IsFinite())
89     return kBothFinite;
90 
91   if (lhs_.IsNaN()) {
92     result_ = kResultIsLHS;
93     return kEitherNaN;
94   }
95 
96   if (rhs_.IsNaN()) {
97     result_ = kResultIsRHS;
98     return kEitherNaN;
99   }
100 
101   if (lhs_.IsInfinity())
102     return rhs_.IsInfinity() ? kBothInfinity : kLHSIsInfinity;
103 
104   DCHECK(rhs_.IsInfinity());
105   return kRHSIsInfinity;
106 }
107 
Value() const108 Decimal SpecialValueHandler::Value() const {
109   DCHECK(result_ == kResultIsLHS || result_ == kResultIsRHS);
110   return (result_ == kResultIsLHS) ? lhs_ : rhs_;
111 }
112 
113 // This class is used for 128 bit unsigned integer arithmetic.
114 class UInt128 {
115   STACK_ALLOCATED();
116 
117  public:
UInt128(uint64_t low,uint64_t high)118   UInt128(uint64_t low, uint64_t high) : high_(high), low_(low) {}
119 
120   UInt128& operator/=(uint32_t);
121 
High() const122   uint64_t High() const { return high_; }
Low() const123   uint64_t Low() const { return low_; }
124 
Multiply(uint64_t u,uint64_t v)125   static UInt128 Multiply(uint64_t u, uint64_t v) {
126     return UInt128(u * v, MultiplyHigh(u, v));
127   }
128 
129  private:
HighUInt32(uint64_t x)130   static uint32_t HighUInt32(uint64_t x) {
131     return static_cast<uint32_t>(x >> 32);
132   }
LowUInt32(uint64_t x)133   static uint32_t LowUInt32(uint64_t x) {
134     return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1));
135   }
MakeUInt64(uint32_t low,uint32_t high)136   static uint64_t MakeUInt64(uint32_t low, uint32_t high) {
137     return low | (static_cast<uint64_t>(high) << 32);
138   }
139 
140   static uint64_t MultiplyHigh(uint64_t, uint64_t);
141 
142   uint64_t high_;
143   uint64_t low_;
144 };
145 
operator /=(const uint32_t divisor)146 UInt128& UInt128::operator/=(const uint32_t divisor) {
147   DCHECK(divisor);
148 
149   if (!high_) {
150     low_ /= divisor;
151     return *this;
152   }
153 
154   uint32_t dividend[4];
155   dividend[0] = LowUInt32(low_);
156   dividend[1] = HighUInt32(low_);
157   dividend[2] = LowUInt32(high_);
158   dividend[3] = HighUInt32(high_);
159 
160   uint32_t quotient[4];
161   uint32_t remainder = 0;
162   for (int i = 3; i >= 0; --i) {
163     const uint64_t work = MakeUInt64(dividend[i], remainder);
164     remainder = static_cast<uint32_t>(work % divisor);
165     quotient[i] = static_cast<uint32_t>(work / divisor);
166   }
167   low_ = MakeUInt64(quotient[0], quotient[1]);
168   high_ = MakeUInt64(quotient[2], quotient[3]);
169   return *this;
170 }
171 
172 // Returns high 64bit of 128bit product.
MultiplyHigh(uint64_t u,uint64_t v)173 uint64_t UInt128::MultiplyHigh(uint64_t u, uint64_t v) {
174   const uint64_t u_low = LowUInt32(u);
175   const uint64_t u_high = HighUInt32(u);
176   const uint64_t v_low = LowUInt32(v);
177   const uint64_t v_high = HighUInt32(v);
178   const uint64_t partial_product = u_high * v_low + HighUInt32(u_low * v_low);
179   return u_high * v_high + HighUInt32(partial_product) +
180          HighUInt32(u_low * v_high + LowUInt32(partial_product));
181 }
182 
CountDigits(uint64_t x)183 static int CountDigits(uint64_t x) {
184   int number_of_digits = 0;
185   for (uint64_t power_of_ten = 1; x >= power_of_ten; power_of_ten *= 10) {
186     ++number_of_digits;
187     if (power_of_ten >= std::numeric_limits<uint64_t>::max() / 10)
188       break;
189   }
190   return number_of_digits;
191 }
192 
ScaleDown(uint64_t x,int n)193 static uint64_t ScaleDown(uint64_t x, int n) {
194   DCHECK_GE(n, 0);
195   while (n > 0 && x) {
196     x /= 10;
197     --n;
198   }
199   return x;
200 }
201 
ScaleUp(uint64_t x,int n)202 static uint64_t ScaleUp(uint64_t x, int n) {
203   DCHECK_GE(n, 0);
204   DCHECK_LE(n, kPrecision);
205 
206   uint64_t y = 1;
207   uint64_t z = 10;
208   for (;;) {
209     if (n & 1)
210       y = y * z;
211 
212     n >>= 1;
213     if (!n)
214       return x * y;
215 
216     z = z * z;
217   }
218 }
219 
220 }  // namespace
221 
EncodedData(Sign sign,FormatClass format_class)222 Decimal::EncodedData::EncodedData(Sign sign, FormatClass format_class)
223     : coefficient_(0), exponent_(0), format_class_(format_class), sign_(sign) {}
224 
EncodedData(Sign sign,int exponent,uint64_t coefficient)225 Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient)
226     : format_class_(coefficient ? kClassNormal : kClassZero), sign_(sign) {
227   if (exponent >= kExponentMin && exponent <= kExponentMax) {
228     while (coefficient > kMaxCoefficient) {
229       coefficient /= 10;
230       ++exponent;
231     }
232   }
233 
234   if (exponent > kExponentMax) {
235     coefficient_ = 0;
236     exponent_ = 0;
237     format_class_ = kClassInfinity;
238     return;
239   }
240 
241   if (exponent < kExponentMin) {
242     coefficient_ = 0;
243     exponent_ = 0;
244     format_class_ = kClassZero;
245     return;
246   }
247 
248   coefficient_ = coefficient;
249   exponent_ = static_cast<int16_t>(exponent);
250 }
251 
operator ==(const EncodedData & another) const252 bool Decimal::EncodedData::operator==(const EncodedData& another) const {
253   return sign_ == another.sign_ && format_class_ == another.format_class_ &&
254          exponent_ == another.exponent_ && coefficient_ == another.coefficient_;
255 }
256 
Decimal(int32_t i32)257 Decimal::Decimal(int32_t i32)
258     : data_(i32 < 0 ? kNegative : kPositive,
259             0,
260             i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32))
261                     : static_cast<uint64_t>(i32)) {}
262 
Decimal(Sign sign,int exponent,uint64_t coefficient)263 Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
264     : data_(sign, exponent, coefficient) {}
265 
Decimal(const EncodedData & data)266 Decimal::Decimal(const EncodedData& data) : data_(data) {}
267 
268 Decimal::Decimal(const Decimal& other) = default;
269 
270 Decimal& Decimal::operator=(const Decimal& other) = default;
271 
operator +=(const Decimal & other)272 Decimal& Decimal::operator+=(const Decimal& other) {
273   data_ = (*this + other).data_;
274   return *this;
275 }
276 
operator -=(const Decimal & other)277 Decimal& Decimal::operator-=(const Decimal& other) {
278   data_ = (*this - other).data_;
279   return *this;
280 }
281 
operator *=(const Decimal & other)282 Decimal& Decimal::operator*=(const Decimal& other) {
283   data_ = (*this * other).data_;
284   return *this;
285 }
286 
operator /=(const Decimal & other)287 Decimal& Decimal::operator/=(const Decimal& other) {
288   data_ = (*this / other).data_;
289   return *this;
290 }
291 
operator -() const292 Decimal Decimal::operator-() const {
293   if (IsNaN())
294     return *this;
295 
296   Decimal result(*this);
297   result.data_.SetSign(InvertSign(data_.GetSign()));
298   return result;
299 }
300 
operator +(const Decimal & rhs) const301 Decimal Decimal::operator+(const Decimal& rhs) const {
302   const Decimal& lhs = *this;
303   const Sign lhs_sign = lhs.GetSign();
304   const Sign rhs_sign = rhs.GetSign();
305 
306   SpecialValueHandler handler(lhs, rhs);
307   switch (handler.Handle()) {
308     case SpecialValueHandler::kBothFinite:
309       break;
310 
311     case SpecialValueHandler::kBothInfinity:
312       return lhs_sign == rhs_sign ? lhs : Nan();
313 
314     case SpecialValueHandler::kEitherNaN:
315       return handler.Value();
316 
317     case SpecialValueHandler::kLHSIsInfinity:
318       return lhs;
319 
320     case SpecialValueHandler::kRHSIsInfinity:
321       return rhs;
322   }
323 
324   const AlignedOperands aligned_operands = AlignOperands(lhs, rhs);
325 
326   const uint64_t result =
327       lhs_sign == rhs_sign
328           ? aligned_operands.lhs_coefficient + aligned_operands.rhs_coefficient
329           : aligned_operands.lhs_coefficient - aligned_operands.rhs_coefficient;
330 
331   if (lhs_sign == kNegative && rhs_sign == kPositive && !result)
332     return Decimal(kPositive, aligned_operands.exponent, 0);
333 
334   return static_cast<int64_t>(result) >= 0
335              ? Decimal(lhs_sign, aligned_operands.exponent, result)
336              : Decimal(InvertSign(lhs_sign), aligned_operands.exponent,
337                        -static_cast<int64_t>(result));
338 }
339 
operator -(const Decimal & rhs) const340 Decimal Decimal::operator-(const Decimal& rhs) const {
341   const Decimal& lhs = *this;
342   const Sign lhs_sign = lhs.GetSign();
343   const Sign rhs_sign = rhs.GetSign();
344 
345   SpecialValueHandler handler(lhs, rhs);
346   switch (handler.Handle()) {
347     case SpecialValueHandler::kBothFinite:
348       break;
349 
350     case SpecialValueHandler::kBothInfinity:
351       return lhs_sign == rhs_sign ? Nan() : lhs;
352 
353     case SpecialValueHandler::kEitherNaN:
354       return handler.Value();
355 
356     case SpecialValueHandler::kLHSIsInfinity:
357       return lhs;
358 
359     case SpecialValueHandler::kRHSIsInfinity:
360       return Infinity(InvertSign(rhs_sign));
361   }
362 
363   const AlignedOperands aligned_operands = AlignOperands(lhs, rhs);
364 
365   const uint64_t result =
366       lhs_sign == rhs_sign
367           ? aligned_operands.lhs_coefficient - aligned_operands.rhs_coefficient
368           : aligned_operands.lhs_coefficient + aligned_operands.rhs_coefficient;
369 
370   if (lhs_sign == kNegative && rhs_sign == kNegative && !result)
371     return Decimal(kPositive, aligned_operands.exponent, 0);
372 
373   return static_cast<int64_t>(result) >= 0
374              ? Decimal(lhs_sign, aligned_operands.exponent, result)
375              : Decimal(InvertSign(lhs_sign), aligned_operands.exponent,
376                        -static_cast<int64_t>(result));
377 }
378 
operator *(const Decimal & rhs) const379 Decimal Decimal::operator*(const Decimal& rhs) const {
380   const Decimal& lhs = *this;
381   const Sign lhs_sign = lhs.GetSign();
382   const Sign rhs_sign = rhs.GetSign();
383   const Sign result_sign = lhs_sign == rhs_sign ? kPositive : kNegative;
384 
385   SpecialValueHandler handler(lhs, rhs);
386   switch (handler.Handle()) {
387     case SpecialValueHandler::kBothFinite: {
388       const uint64_t lhs_coefficient = lhs.data_.Coefficient();
389       const uint64_t rhs_coefficient = rhs.data_.Coefficient();
390       int result_exponent = lhs.Exponent() + rhs.Exponent();
391       UInt128 work(UInt128::Multiply(lhs_coefficient, rhs_coefficient));
392       while (work.High()) {
393         work /= 10;
394         ++result_exponent;
395       }
396       return Decimal(result_sign, result_exponent, work.Low());
397     }
398 
399     case SpecialValueHandler::kBothInfinity:
400       return Infinity(result_sign);
401 
402     case SpecialValueHandler::kEitherNaN:
403       return handler.Value();
404 
405     case SpecialValueHandler::kLHSIsInfinity:
406       return rhs.IsZero() ? Nan() : Infinity(result_sign);
407 
408     case SpecialValueHandler::kRHSIsInfinity:
409       return lhs.IsZero() ? Nan() : Infinity(result_sign);
410   }
411 
412   NOTREACHED();
413   return Nan();
414 }
415 
operator /(const Decimal & rhs) const416 Decimal Decimal::operator/(const Decimal& rhs) const {
417   const Decimal& lhs = *this;
418   const Sign lhs_sign = lhs.GetSign();
419   const Sign rhs_sign = rhs.GetSign();
420   const Sign result_sign = lhs_sign == rhs_sign ? kPositive : kNegative;
421 
422   SpecialValueHandler handler(lhs, rhs);
423   switch (handler.Handle()) {
424     case SpecialValueHandler::kBothFinite:
425       break;
426 
427     case SpecialValueHandler::kBothInfinity:
428       return Nan();
429 
430     case SpecialValueHandler::kEitherNaN:
431       return handler.Value();
432 
433     case SpecialValueHandler::kLHSIsInfinity:
434       return Infinity(result_sign);
435 
436     case SpecialValueHandler::kRHSIsInfinity:
437       return Zero(result_sign);
438   }
439 
440   DCHECK(lhs.IsFinite());
441   DCHECK(rhs.IsFinite());
442 
443   if (rhs.IsZero())
444     return lhs.IsZero() ? Nan() : Infinity(result_sign);
445 
446   int result_exponent = lhs.Exponent() - rhs.Exponent();
447 
448   if (lhs.IsZero())
449     return Decimal(result_sign, result_exponent, 0);
450 
451   uint64_t remainder = lhs.data_.Coefficient();
452   const uint64_t divisor = rhs.data_.Coefficient();
453   uint64_t result = 0;
454   for (;;) {
455     while (remainder < divisor && result < kMaxCoefficient / 10) {
456       remainder *= 10;
457       result *= 10;
458       --result_exponent;
459     }
460     if (remainder < divisor)
461       break;
462     uint64_t quotient = remainder / divisor;
463     if (result > kMaxCoefficient - quotient)
464       break;
465     result += quotient;
466     remainder %= divisor;
467     if (!remainder)
468       break;
469   }
470 
471   if (remainder > divisor / 2)
472     ++result;
473 
474   return Decimal(result_sign, result_exponent, result);
475 }
476 
operator ==(const Decimal & rhs) const477 bool Decimal::operator==(const Decimal& rhs) const {
478   return data_ == rhs.data_ || CompareTo(rhs).IsZero();
479 }
480 
operator !=(const Decimal & rhs) const481 bool Decimal::operator!=(const Decimal& rhs) const {
482   if (data_ == rhs.data_)
483     return false;
484   const Decimal result = CompareTo(rhs);
485   if (result.IsNaN())
486     return false;
487   return !result.IsZero();
488 }
489 
operator <(const Decimal & rhs) const490 bool Decimal::operator<(const Decimal& rhs) const {
491   const Decimal result = CompareTo(rhs);
492   if (result.IsNaN())
493     return false;
494   return !result.IsZero() && result.IsNegative();
495 }
496 
operator <=(const Decimal & rhs) const497 bool Decimal::operator<=(const Decimal& rhs) const {
498   if (data_ == rhs.data_)
499     return true;
500   const Decimal result = CompareTo(rhs);
501   if (result.IsNaN())
502     return false;
503   return result.IsZero() || result.IsNegative();
504 }
505 
operator >(const Decimal & rhs) const506 bool Decimal::operator>(const Decimal& rhs) const {
507   const Decimal result = CompareTo(rhs);
508   if (result.IsNaN())
509     return false;
510   return !result.IsZero() && result.IsPositive();
511 }
512 
operator >=(const Decimal & rhs) const513 bool Decimal::operator>=(const Decimal& rhs) const {
514   if (data_ == rhs.data_)
515     return true;
516   const Decimal result = CompareTo(rhs);
517   if (result.IsNaN())
518     return false;
519   return result.IsZero() || !result.IsNegative();
520 }
521 
Abs() const522 Decimal Decimal::Abs() const {
523   Decimal result(*this);
524   result.data_.SetSign(kPositive);
525   return result;
526 }
527 
AlignOperands(const Decimal & lhs,const Decimal & rhs)528 Decimal::AlignedOperands Decimal::AlignOperands(const Decimal& lhs,
529                                                 const Decimal& rhs) {
530   DCHECK(lhs.IsFinite());
531   DCHECK(rhs.IsFinite());
532 
533   const int lhs_exponent = lhs.Exponent();
534   const int rhs_exponent = rhs.Exponent();
535   int exponent = std::min(lhs_exponent, rhs_exponent);
536   uint64_t lhs_coefficient = lhs.data_.Coefficient();
537   uint64_t rhs_coefficient = rhs.data_.Coefficient();
538 
539   if (lhs_exponent > rhs_exponent) {
540     const int number_of_lhs_digits = CountDigits(lhs_coefficient);
541     if (number_of_lhs_digits) {
542       const int lhs_shift_amount = lhs_exponent - rhs_exponent;
543       const int overflow = number_of_lhs_digits + lhs_shift_amount - kPrecision;
544       if (overflow <= 0) {
545         lhs_coefficient = ScaleUp(lhs_coefficient, lhs_shift_amount);
546       } else {
547         lhs_coefficient = ScaleUp(lhs_coefficient, lhs_shift_amount - overflow);
548         rhs_coefficient = ScaleDown(rhs_coefficient, overflow);
549         exponent += overflow;
550       }
551     }
552 
553   } else if (lhs_exponent < rhs_exponent) {
554     const int number_of_rhs_digits = CountDigits(rhs_coefficient);
555     if (number_of_rhs_digits) {
556       const int rhs_shift_amount = rhs_exponent - lhs_exponent;
557       const int overflow = number_of_rhs_digits + rhs_shift_amount - kPrecision;
558       if (overflow <= 0) {
559         rhs_coefficient = ScaleUp(rhs_coefficient, rhs_shift_amount);
560       } else {
561         rhs_coefficient = ScaleUp(rhs_coefficient, rhs_shift_amount - overflow);
562         lhs_coefficient = ScaleDown(lhs_coefficient, overflow);
563         exponent += overflow;
564       }
565     }
566   }
567 
568   AlignedOperands aligned_operands;
569   aligned_operands.exponent = exponent;
570   aligned_operands.lhs_coefficient = lhs_coefficient;
571   aligned_operands.rhs_coefficient = rhs_coefficient;
572   return aligned_operands;
573 }
574 
IsMultiplePowersOfTen(uint64_t coefficient,int n)575 static bool IsMultiplePowersOfTen(uint64_t coefficient, int n) {
576   return !coefficient || !(coefficient % ScaleUp(1, n));
577 }
578 
579 // Round toward positive infinity.
Ceil() const580 Decimal Decimal::Ceil() const {
581   if (IsSpecial())
582     return *this;
583 
584   if (Exponent() >= 0)
585     return *this;
586 
587   uint64_t result = data_.Coefficient();
588   const int number_of_digits = CountDigits(result);
589   const int number_of_drop_digits = -Exponent();
590   if (number_of_digits <= number_of_drop_digits)
591     return IsPositive() ? Decimal(1) : Zero(kPositive);
592 
593   result = ScaleDown(result, number_of_drop_digits);
594   if (IsPositive() &&
595       !IsMultiplePowersOfTen(data_.Coefficient(), number_of_drop_digits))
596     ++result;
597   return Decimal(GetSign(), 0, result);
598 }
599 
CompareTo(const Decimal & rhs) const600 Decimal Decimal::CompareTo(const Decimal& rhs) const {
601   const Decimal result(*this - rhs);
602   switch (result.data_.GetFormatClass()) {
603     case EncodedData::kClassInfinity:
604       return result.IsNegative() ? Decimal(-1) : Decimal(1);
605 
606     case EncodedData::kClassNaN:
607     case EncodedData::kClassNormal:
608       return result;
609 
610     case EncodedData::kClassZero:
611       return Zero(kPositive);
612 
613     default:
614       NOTREACHED();
615       return Nan();
616   }
617 }
618 
619 // Round toward negative infinity.
Floor() const620 Decimal Decimal::Floor() const {
621   if (IsSpecial())
622     return *this;
623 
624   if (Exponent() >= 0)
625     return *this;
626 
627   uint64_t result = data_.Coefficient();
628   const int number_of_digits = CountDigits(result);
629   const int number_of_drop_digits = -Exponent();
630   if (number_of_digits < number_of_drop_digits)
631     return IsPositive() ? Zero(kPositive) : Decimal(-1);
632 
633   result = ScaleDown(result, number_of_drop_digits);
634   if (IsNegative() &&
635       !IsMultiplePowersOfTen(data_.Coefficient(), number_of_drop_digits))
636     ++result;
637   return Decimal(GetSign(), 0, result);
638 }
639 
FromDouble(double double_value)640 Decimal Decimal::FromDouble(double double_value) {
641   if (std::isfinite(double_value))
642     return FromString(String::NumberToStringECMAScript(double_value));
643 
644   if (std::isinf(double_value))
645     return Infinity(double_value < 0 ? kNegative : kPositive);
646 
647   return Nan();
648 }
649 
FromString(const String & str)650 Decimal Decimal::FromString(const String& str) {
651   int exponent = 0;
652   Sign exponent_sign = kPositive;
653   int number_of_digits = 0;
654   int number_of_digits_after_dot = 0;
655   int number_of_extra_digits = 0;
656   Sign sign = kPositive;
657 
658   enum {
659     kStateDigit,
660     kStateDot,
661     kStateDotDigit,
662     kStateE,
663     kStateEDigit,
664     kStateESign,
665     kStateSign,
666     kStateStart,
667     kStateZero,
668   } state = kStateStart;
669 
670 #define HandleCharAndBreak(expected, nextState) \
671   if (ch == expected) {                         \
672     state = nextState;                          \
673     break;                                      \
674   }
675 
676 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
677   if (ch == expected1 || ch == expected2) {                     \
678     state = nextState;                                          \
679     break;                                                      \
680   }
681 
682   uint64_t accumulator = 0;
683   for (unsigned index = 0; index < str.length(); ++index) {
684     const int ch = str[index];
685     switch (state) {
686       case kStateDigit:
687         if (ch >= '0' && ch <= '9') {
688           if (number_of_digits < kPrecision) {
689             ++number_of_digits;
690             accumulator *= 10;
691             accumulator += ch - '0';
692           } else {
693             ++number_of_extra_digits;
694           }
695           break;
696         }
697 
698         HandleCharAndBreak('.', kStateDot);
699         HandleTwoCharsAndBreak('E', 'e', kStateE);
700         return Nan();
701 
702       case kStateDot:
703       case kStateDotDigit:
704         if (ch >= '0' && ch <= '9') {
705           if (number_of_digits < kPrecision) {
706             ++number_of_digits;
707             ++number_of_digits_after_dot;
708             accumulator *= 10;
709             accumulator += ch - '0';
710           }
711           state = kStateDotDigit;
712           break;
713         }
714 
715         HandleTwoCharsAndBreak('E', 'e', kStateE);
716         return Nan();
717 
718       case kStateE:
719         if (ch == '+') {
720           exponent_sign = kPositive;
721           state = kStateESign;
722           break;
723         }
724 
725         if (ch == '-') {
726           exponent_sign = kNegative;
727           state = kStateESign;
728           break;
729         }
730 
731         if (ch >= '0' && ch <= '9') {
732           exponent = ch - '0';
733           state = kStateEDigit;
734           break;
735         }
736 
737         return Nan();
738 
739       case kStateEDigit:
740         if (ch >= '0' && ch <= '9') {
741           exponent *= 10;
742           exponent += ch - '0';
743           if (exponent > kExponentMax + kPrecision) {
744             if (accumulator)
745               return exponent_sign == kNegative ? Zero(kPositive)
746                                                 : Infinity(sign);
747             return Zero(sign);
748           }
749           state = kStateEDigit;
750           break;
751         }
752 
753         return Nan();
754 
755       case kStateESign:
756         if (ch >= '0' && ch <= '9') {
757           exponent = ch - '0';
758           state = kStateEDigit;
759           break;
760         }
761 
762         return Nan();
763 
764       case kStateSign:
765         if (ch >= '1' && ch <= '9') {
766           accumulator = ch - '0';
767           number_of_digits = 1;
768           state = kStateDigit;
769           break;
770         }
771 
772         HandleCharAndBreak('0', kStateZero);
773         HandleCharAndBreak('.', kStateDot);
774         return Nan();
775 
776       case kStateStart:
777         if (ch >= '1' && ch <= '9') {
778           accumulator = ch - '0';
779           number_of_digits = 1;
780           state = kStateDigit;
781           break;
782         }
783 
784         if (ch == '-') {
785           sign = kNegative;
786           state = kStateSign;
787           break;
788         }
789 
790         if (ch == '+') {
791           sign = kPositive;
792           state = kStateSign;
793           break;
794         }
795 
796         HandleCharAndBreak('0', kStateZero);
797         HandleCharAndBreak('.', kStateDot);
798         return Nan();
799 
800       case kStateZero:
801         if (ch == '0')
802           break;
803 
804         if (ch >= '1' && ch <= '9') {
805           accumulator = ch - '0';
806           number_of_digits = 1;
807           state = kStateDigit;
808           break;
809         }
810 
811         HandleCharAndBreak('.', kStateDot);
812         HandleTwoCharsAndBreak('E', 'e', kStateE);
813         return Nan();
814 
815       default:
816         NOTREACHED();
817         return Nan();
818     }
819   }
820 
821   if (state == kStateZero)
822     return Zero(sign);
823 
824   if (state == kStateDigit || state == kStateEDigit ||
825       state == kStateDotDigit) {
826     int result_exponent = exponent * (exponent_sign == kNegative ? -1 : 1) -
827                           number_of_digits_after_dot + number_of_extra_digits;
828     if (result_exponent < kExponentMin)
829       return Zero(kPositive);
830 
831     const int overflow = result_exponent - kExponentMax + 1;
832     if (overflow > 0) {
833       if (overflow + number_of_digits - number_of_digits_after_dot > kPrecision)
834         return Infinity(sign);
835       accumulator = ScaleUp(accumulator, overflow);
836       result_exponent -= overflow;
837     }
838 
839     return Decimal(sign, result_exponent, accumulator);
840   }
841 
842   return Nan();
843 }
844 
Infinity(const Sign sign)845 Decimal Decimal::Infinity(const Sign sign) {
846   return Decimal(EncodedData(sign, EncodedData::kClassInfinity));
847 }
848 
Nan()849 Decimal Decimal::Nan() {
850   return Decimal(EncodedData(kPositive, EncodedData::kClassNaN));
851 }
852 
Remainder(const Decimal & rhs) const853 Decimal Decimal::Remainder(const Decimal& rhs) const {
854   const Decimal quotient = *this / rhs;
855   return quotient.IsSpecial()
856              ? quotient
857              : *this - (quotient.IsNegative() ? quotient.Ceil()
858                                               : quotient.Floor()) *
859                            rhs;
860 }
861 
Round() const862 Decimal Decimal::Round() const {
863   if (IsSpecial())
864     return *this;
865 
866   if (Exponent() >= 0)
867     return *this;
868 
869   uint64_t result = data_.Coefficient();
870   const int number_of_digits = CountDigits(result);
871   const int number_of_drop_digits = -Exponent();
872   if (number_of_digits < number_of_drop_digits)
873     return Zero(kPositive);
874 
875   result = ScaleDown(result, number_of_drop_digits - 1);
876   if (result % 10 >= 5)
877     result += 10;
878   result /= 10;
879   return Decimal(GetSign(), 0, result);
880 }
881 
ToDouble() const882 double Decimal::ToDouble() const {
883   if (IsFinite()) {
884     bool valid;
885     const double double_value = ToString().ToDouble(&valid);
886     return valid ? double_value : std::numeric_limits<double>::quiet_NaN();
887   }
888 
889   if (IsInfinity())
890     return IsNegative() ? -std::numeric_limits<double>::infinity()
891                         : std::numeric_limits<double>::infinity();
892 
893   return std::numeric_limits<double>::quiet_NaN();
894 }
895 
ToString() const896 String Decimal::ToString() const {
897   switch (data_.GetFormatClass()) {
898     case EncodedData::kClassInfinity:
899       return GetSign() ? "-Infinity" : "Infinity";
900 
901     case EncodedData::kClassNaN:
902       return "NaN";
903 
904     case EncodedData::kClassNormal:
905     case EncodedData::kClassZero:
906       break;
907 
908     default:
909       NOTREACHED();
910       return "";
911   }
912 
913   StringBuilder builder;
914   if (GetSign())
915     builder.Append('-');
916 
917   int original_exponent = Exponent();
918   uint64_t coefficient = data_.Coefficient();
919 
920   if (original_exponent < 0) {
921     const int kMaxDigits = DBL_DIG;
922     uint64_t last_digit = 0;
923     while (CountDigits(coefficient) > kMaxDigits) {
924       last_digit = coefficient % 10;
925       coefficient /= 10;
926       ++original_exponent;
927     }
928 
929     if (last_digit >= 5)
930       ++coefficient;
931 
932     while (original_exponent < 0 && coefficient && !(coefficient % 10)) {
933       coefficient /= 10;
934       ++original_exponent;
935     }
936   }
937 
938   const String digits = String::Number(coefficient);
939   int coefficient_length = static_cast<int>(digits.length());
940   const int adjusted_exponent = original_exponent + coefficient_length - 1;
941   if (original_exponent <= 0 && adjusted_exponent >= -6) {
942     if (!original_exponent) {
943       builder.Append(digits);
944       return builder.ToString();
945     }
946 
947     if (adjusted_exponent >= 0) {
948       for (int i = 0; i < coefficient_length; ++i) {
949         builder.Append(digits[i]);
950         if (i == adjusted_exponent)
951           builder.Append('.');
952       }
953       return builder.ToString();
954     }
955 
956     builder.Append("0.");
957     for (int i = adjusted_exponent + 1; i < 0; ++i)
958       builder.Append('0');
959 
960     builder.Append(digits);
961 
962   } else {
963     builder.Append(digits[0]);
964     while (coefficient_length >= 2 && digits[coefficient_length - 1] == '0')
965       --coefficient_length;
966     if (coefficient_length >= 2) {
967       builder.Append('.');
968       for (int i = 1; i < coefficient_length; ++i)
969         builder.Append(digits[i]);
970     }
971 
972     if (adjusted_exponent) {
973       builder.Append(adjusted_exponent < 0 ? "e" : "e+");
974       builder.AppendNumber(adjusted_exponent);
975     }
976   }
977   return builder.ToString();
978 }
979 
Zero(Sign sign)980 Decimal Decimal::Zero(Sign sign) {
981   return Decimal(EncodedData(sign, EncodedData::kClassZero));
982 }
983 
operator <<(std::ostream & ostream,const Decimal & decimal)984 std::ostream& operator<<(std::ostream& ostream, const Decimal& decimal) {
985   Decimal::EncodedData data = decimal.Value();
986   return ostream << "encode(" << String::Number(data.Coefficient()).Ascii()
987                  << ", " << String::Number(data.Exponent()).Ascii() << ", "
988                  << (data.GetSign() == Decimal::kNegative ? "Negative"
989                                                           : "Positive")
990                  << ")=" << decimal.ToString().Ascii();
991 }
992 
993 }  // namespace blink
994