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
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
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.
32 #include "platform/Decimal.h"
34 #include "wtf/MathExtras.h"
35 #include "wtf/Noncopyable.h"
36 #include "wtf/text/StringBuilder.h"
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
);
63 SpecialValueHandler(const Decimal
& lhs
, const Decimal
& rhs
);
64 HandleResult
handle();
65 Decimal
value() const;
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())
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
;
96 if (rhsClass
== Decimal::EncodedData::ClassNaN
) {
97 m_result
= ResultIsRHS
;
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();
111 Decimal
SpecialValueHandler::value() const
118 case ResultIsUnknown
:
120 ASSERT_NOT_REACHED();
125 // This class is used for 128 bit unsigned integer arithmetic.
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
)); }
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);
151 UInt128
& UInt128::operator/=(const uint32_t divisor
)
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]);
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) {
194 if (powerOfTen
>= std::numeric_limits
<uint64_t>::max() / 10)
197 return numberOfDigits
;
200 static uint64_t scaleDown(uint64_t x
, int n
)
210 static uint64_t scaleUp(uint64_t x
, int n
)
213 ASSERT(n
< Precision
);
229 } // namespace DecimalPrivate
231 using namespace DecimalPrivate
;
233 Decimal::EncodedData::EncodedData(Sign sign
, FormatClass formatClass
)
236 , m_formatClass(formatClass
)
241 Decimal::EncodedData::EncodedData(Sign sign
, int exponent
, uint64_t coefficient
)
242 : m_formatClass(coefficient
? ClassNormal
: ClassZero
)
245 if (exponent
>= ExponentMin
&& exponent
<= ExponentMax
) {
246 while (coefficient
> MaxCoefficient
) {
252 if (exponent
> ExponentMax
) {
255 m_formatClass
= ClassInfinity
;
259 if (exponent
< ExponentMin
) {
262 m_formatClass
= ClassZero
;
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
)
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
;
304 Decimal
& Decimal::operator+=(const Decimal
& other
)
306 m_data
= (*this + other
).m_data
;
310 Decimal
& Decimal::operator-=(const Decimal
& other
)
312 m_data
= (*this - other
).m_data
;
316 Decimal
& Decimal::operator*=(const Decimal
& other
)
318 m_data
= (*this * other
).m_data
;
322 Decimal
& Decimal::operator/=(const Decimal
& other
)
324 m_data
= (*this / other
).m_data
;
328 Decimal
Decimal::operator-() const
333 Decimal
result(*this);
334 result
.m_data
.setSign(invertSign(m_data
.sign()));
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
:
349 case SpecialValueHandler::BothInfinity
:
350 return lhsSign
== rhsSign
? lhs
: nan();
352 case SpecialValueHandler::EitherNaN
:
353 return handler
.value();
355 case SpecialValueHandler::LHSIsInfinity
:
358 case SpecialValueHandler::RHSIsInfinity
:
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
:
387 case SpecialValueHandler::BothInfinity
:
388 return lhsSign
== rhsSign
? nan() : lhs
;
390 case SpecialValueHandler::EitherNaN
:
391 return handler
.value();
393 case SpecialValueHandler::LHSIsInfinity
:
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()) {
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();
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
:
464 case SpecialValueHandler::BothInfinity
:
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());
481 return lhs
.isZero() ? nan() : infinity(resultSign
);
483 int resultExponent
= lhs
.exponent() - rhs
.exponent();
486 return Decimal(resultSign
, resultExponent
, 0);
488 uint64_t remainder
= lhs
.m_data
.coefficient();
489 const uint64_t divisor
= rhs
.m_data
.coefficient();
492 while (remainder
< divisor
&& result
< MaxCoefficient
/ 10) {
497 if (remainder
< divisor
)
499 uint64_t quotient
= remainder
/ divisor
;
500 if (result
> MaxCoefficient
- quotient
)
503 remainder
%= divisor
;
508 if (remainder
> divisor
/ 2)
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
)
523 const Decimal result
= compareTo(rhs
);
526 return !result
.isZero();
529 bool Decimal::operator<(const Decimal
& rhs
) const
531 const Decimal result
= compareTo(rhs
);
534 return !result
.isZero() && result
.isNegative();
537 bool Decimal::operator<=(const Decimal
& rhs
) const
539 if (m_data
== rhs
.m_data
)
541 const Decimal result
= compareTo(rhs
);
544 return result
.isZero() || result
.isNegative();
547 bool Decimal::operator>(const Decimal
& rhs
) const
549 const Decimal result
= compareTo(rhs
);
552 return !result
.isZero() && result
.isPositive();
555 bool Decimal::operator>=(const Decimal
& rhs
) const
557 if (m_data
== rhs
.m_data
)
559 const Decimal result
= compareTo(rhs
);
562 return result
.isZero() || !result
.isNegative();
565 Decimal
Decimal::abs() const
567 Decimal
result(*this);
568 result
.m_data
.setSign(Positive
);
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
;
589 lhsCoefficient
= scaleUp(lhsCoefficient
, lhsShiftAmount
);
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
;
603 rhsCoefficient
= scaleUp(rhsCoefficient
, rhsShiftAmount
);
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
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
))
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
:
656 case EncodedData::ClassZero
:
657 return zero(Positive
);
660 ASSERT_NOT_REACHED();
665 // Round toward negative infinity.
666 Decimal
Decimal::floor() const
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
))
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
);
697 Decimal
Decimal::fromString(const String
& str
)
700 Sign exponentSign
= Positive
;
701 int numberOfDigits
= 0;
702 int numberOfDigitsAfterDot
= 0;
703 int numberOfExtraDigits
= 0;
704 Sign sign
= Positive
;
716 } state
= StateStart
;
718 #define HandleCharAndBreak(expected, nextState) \
719 if (ch == expected) { \
724 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
725 if (ch == expected1 || ch == expected2) { \
730 uint64_t accumulator
= 0;
731 for (unsigned index
= 0; index
< str
.length(); ++index
) {
732 const int ch
= str
[index
];
735 if (ch
>= '0' && ch
<= '9') {
736 if (numberOfDigits
< Precision
) {
739 accumulator
+= ch
- '0';
741 ++numberOfExtraDigits
;
746 HandleCharAndBreak('.', StateDot
);
747 HandleTwoCharsAndBreak('E', 'e', StateE
);
752 if (ch
>= '0' && ch
<= '9') {
753 if (numberOfDigits
< Precision
) {
755 ++numberOfDigitsAfterDot
;
757 accumulator
+= ch
- '0';
759 state
= StateDotDigit
;
763 HandleTwoCharsAndBreak('E', 'e', StateE
);
768 exponentSign
= Positive
;
774 exponentSign
= Negative
;
779 if (ch
>= '0' && ch
<= '9') {
788 if (ch
>= '0' && ch
<= '9') {
790 exponent
+= ch
- '0';
791 if (exponent
> ExponentMax
+ Precision
) {
793 return exponentSign
== Negative
? zero(Positive
) : infinity(sign
);
803 if (ch
>= '0' && ch
<= '9') {
812 if (ch
>= '1' && ch
<= '9') {
813 accumulator
= ch
- '0';
819 HandleCharAndBreak('0', StateZero
);
823 if (ch
>= '1' && ch
<= '9') {
824 accumulator
= ch
- '0';
842 HandleCharAndBreak('0', StateZero
);
843 HandleCharAndBreak('.', StateDot
);
850 if (ch
>= '1' && ch
<= '9') {
851 accumulator
= ch
- '0';
857 HandleCharAndBreak('.', StateDot
);
858 HandleTwoCharsAndBreak('E', 'e', StateE
);
862 ASSERT_NOT_REACHED();
867 if (state
== StateZero
)
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;
877 if (overflow
+ numberOfDigits
- numberOfDigitsAfterDot
> Precision
)
878 return infinity(sign
);
879 accumulator
= scaleUp(accumulator
, overflow
);
880 resultExponent
-= overflow
;
883 return Decimal(sign
, resultExponent
, accumulator
);
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
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)
923 return Decimal(sign(), 0, result
);
926 double Decimal::toDouble() const
930 const double doubleValue
= toString().toDouble(&valid
);
931 return valid
? doubleValue
: std::numeric_limits
<double>::quiet_NaN();
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
:
949 case EncodedData::ClassNormal
:
950 case EncodedData::ClassZero
:
954 ASSERT_NOT_REACHED();
958 StringBuilder builder
;
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;
977 while (originalExponent
< 0 && coefficient
&& !(coefficient
% 10)) {
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
)
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
);
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