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 "moz-decimal-utils.h"
33 #include "DoubleConversion.h"
35 using namespace moz_decimal_utils
;
42 namespace DecimalPrivate
{
44 // This class handles Decimal special values.
45 class SpecialValueHandler
{
47 WTF_MAKE_NONCOPYABLE(SpecialValueHandler
);
57 SpecialValueHandler(const Decimal
& lhs
, const Decimal
& rhs
);
58 HandleResult
handle();
59 Decimal
value() const;
73 SpecialValueHandler::SpecialValueHandler(const Decimal
& lhs
, const Decimal
& rhs
)
74 : m_lhs(lhs
), m_rhs(rhs
), m_result(ResultIsUnknown
)
78 SpecialValueHandler::HandleResult
SpecialValueHandler::handle()
80 if (m_lhs
.isFinite() && m_rhs
.isFinite())
83 const Decimal::EncodedData::FormatClass lhsClass
= m_lhs
.value().formatClass();
84 const Decimal::EncodedData::FormatClass rhsClass
= m_rhs
.value().formatClass();
85 if (lhsClass
== Decimal::EncodedData::ClassNaN
) {
86 m_result
= ResultIsLHS
;
90 if (rhsClass
== Decimal::EncodedData::ClassNaN
) {
91 m_result
= ResultIsRHS
;
95 if (lhsClass
== Decimal::EncodedData::ClassInfinity
)
96 return rhsClass
== Decimal::EncodedData::ClassInfinity
? BothInfinity
: LHSIsInfinity
;
98 if (rhsClass
== Decimal::EncodedData::ClassInfinity
)
101 ASSERT_NOT_REACHED();
105 Decimal
SpecialValueHandler::value() const
112 case ResultIsUnknown
:
114 ASSERT_NOT_REACHED();
119 // This class is used for 128 bit unsigned integer arithmetic.
122 UInt128(uint64_t low
, uint64_t high
)
123 : m_high(high
), m_low(low
)
127 UInt128
& operator/=(uint32_t);
129 uint64_t high() const { return m_high
; }
130 uint64_t low() const { return m_low
; }
132 static UInt128
multiply(uint64_t u
, uint64_t v
) { return UInt128(u
* v
, multiplyHigh(u
, v
)); }
135 static uint32_t highUInt32(uint64_t x
) { return static_cast<uint32_t>(x
>> 32); }
136 static uint32_t lowUInt32(uint64_t x
) { return static_cast<uint32_t>(x
& ((static_cast<uint64_t>(1) << 32) - 1)); }
137 static uint64_t makeUInt64(uint32_t low
, uint32_t high
) { return low
| (static_cast<uint64_t>(high
) << 32); }
139 static uint64_t multiplyHigh(uint64_t, uint64_t);
145 UInt128
& UInt128::operator/=(const uint32_t divisor
)
154 uint32_t dividend
[4];
155 dividend
[0] = lowUInt32(m_low
);
156 dividend
[1] = highUInt32(m_low
);
157 dividend
[2] = lowUInt32(m_high
);
158 dividend
[3] = highUInt32(m_high
);
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
);
167 m_low
= makeUInt64(quotient
[0], quotient
[1]);
168 m_high
= makeUInt64(quotient
[2], quotient
[3]);
172 // Returns high 64bit of 128bit product.
173 uint64_t UInt128::multiplyHigh(uint64_t u
, uint64_t v
)
175 const uint64_t uLow
= lowUInt32(u
);
176 const uint64_t uHigh
= highUInt32(u
);
177 const uint64_t vLow
= lowUInt32(v
);
178 const uint64_t vHigh
= highUInt32(v
);
179 const uint64_t partialProduct
= uHigh
* vLow
+ highUInt32(uLow
* vLow
);
180 return uHigh
* vHigh
+ highUInt32(partialProduct
) + highUInt32(uLow
* vHigh
+ lowUInt32(partialProduct
));
183 static int countDigits(uint64_t x
)
185 int numberOfDigits
= 0;
186 for (uint64_t powerOfTen
= 1; x
>= powerOfTen
; powerOfTen
*= 10) {
188 if (powerOfTen
>= std::numeric_limits
<uint64_t>::max() / 10)
191 return numberOfDigits
;
194 static uint64_t scaleDown(uint64_t x
, int n
)
204 static uint64_t scaleUp(uint64_t x
, int n
)
207 ASSERT(n
<= Precision
);
223 } // namespace DecimalPrivate
225 using namespace DecimalPrivate
;
227 bool Decimal::EncodedData::operator==(const EncodedData
& another
) const
229 return m_sign
== another
.m_sign
230 && m_formatClass
== another
.m_formatClass
231 && m_exponent
== another
.m_exponent
232 && m_coefficient
== another
.m_coefficient
;
236 Decimal::Decimal(int32_t i32
)
237 : Decimal(DecimalLiteral
{i32
}) {}
239 Decimal::Decimal(Sign sign
, int exponent
, uint64_t coefficient
)
240 : m_data(sign
, coefficient
? exponent
: 0, coefficient
) {}
242 Decimal::Decimal(const Decimal
& other
)
243 : m_data(other
.m_data
)
247 Decimal
& Decimal::operator=(const Decimal
& other
)
249 m_data
= other
.m_data
;
253 Decimal
& Decimal::operator+=(const Decimal
& other
)
255 m_data
= (*this + other
).m_data
;
259 Decimal
& Decimal::operator-=(const Decimal
& other
)
261 m_data
= (*this - other
).m_data
;
265 Decimal
& Decimal::operator*=(const Decimal
& other
)
267 m_data
= (*this * other
).m_data
;
271 Decimal
& Decimal::operator/=(const Decimal
& other
)
273 m_data
= (*this / other
).m_data
;
277 Decimal
Decimal::operator-() const
282 Decimal
result(*this);
283 result
.m_data
.setSign(invertSign(m_data
.sign()));
287 Decimal
Decimal::operator+(const Decimal
& rhs
) const
289 const Decimal
& lhs
= *this;
290 const Sign lhsSign
= lhs
.sign();
291 const Sign rhsSign
= rhs
.sign();
293 SpecialValueHandler
handler(lhs
, rhs
);
294 switch (handler
.handle()) {
295 case SpecialValueHandler::BothFinite
:
298 case SpecialValueHandler::BothInfinity
:
299 return lhsSign
== rhsSign
? lhs
: nan();
301 case SpecialValueHandler::EitherNaN
:
302 return handler
.value();
304 case SpecialValueHandler::LHSIsInfinity
:
307 case SpecialValueHandler::RHSIsInfinity
:
311 const AlignedOperands alignedOperands
= alignOperands(lhs
, rhs
);
313 const uint64_t result
= lhsSign
== rhsSign
314 ? alignedOperands
.lhsCoefficient
+ alignedOperands
.rhsCoefficient
315 : alignedOperands
.lhsCoefficient
- alignedOperands
.rhsCoefficient
;
317 if (lhsSign
== Negative
&& rhsSign
== Positive
&& !result
)
318 return Decimal(Positive
, alignedOperands
.exponent
, 0);
320 return static_cast<int64_t>(result
) >= 0
321 ? Decimal(lhsSign
, alignedOperands
.exponent
, result
)
322 : Decimal(invertSign(lhsSign
), alignedOperands
.exponent
, -static_cast<int64_t>(result
));
325 Decimal
Decimal::operator-(const Decimal
& rhs
) const
327 const Decimal
& lhs
= *this;
328 const Sign lhsSign
= lhs
.sign();
329 const Sign rhsSign
= rhs
.sign();
331 SpecialValueHandler
handler(lhs
, rhs
);
332 switch (handler
.handle()) {
333 case SpecialValueHandler::BothFinite
:
336 case SpecialValueHandler::BothInfinity
:
337 return lhsSign
== rhsSign
? nan() : lhs
;
339 case SpecialValueHandler::EitherNaN
:
340 return handler
.value();
342 case SpecialValueHandler::LHSIsInfinity
:
345 case SpecialValueHandler::RHSIsInfinity
:
346 return infinity(invertSign(rhsSign
));
349 const AlignedOperands alignedOperands
= alignOperands(lhs
, rhs
);
351 const uint64_t result
= lhsSign
== rhsSign
352 ? alignedOperands
.lhsCoefficient
- alignedOperands
.rhsCoefficient
353 : alignedOperands
.lhsCoefficient
+ alignedOperands
.rhsCoefficient
;
355 if (lhsSign
== Negative
&& rhsSign
== Negative
&& !result
)
356 return Decimal(Positive
, alignedOperands
.exponent
, 0);
358 return static_cast<int64_t>(result
) >= 0
359 ? Decimal(lhsSign
, alignedOperands
.exponent
, result
)
360 : Decimal(invertSign(lhsSign
), alignedOperands
.exponent
, -static_cast<int64_t>(result
));
363 Decimal
Decimal::operator*(const Decimal
& rhs
) const
365 const Decimal
& lhs
= *this;
366 const Sign lhsSign
= lhs
.sign();
367 const Sign rhsSign
= rhs
.sign();
368 const Sign resultSign
= lhsSign
== rhsSign
? Positive
: Negative
;
370 SpecialValueHandler
handler(lhs
, rhs
);
371 switch (handler
.handle()) {
372 case SpecialValueHandler::BothFinite
: {
373 const uint64_t lhsCoefficient
= lhs
.m_data
.coefficient();
374 const uint64_t rhsCoefficient
= rhs
.m_data
.coefficient();
375 int resultExponent
= lhs
.exponent() + rhs
.exponent();
376 UInt128
work(UInt128::multiply(lhsCoefficient
, rhsCoefficient
));
377 while (work
.high()) {
381 return Decimal(resultSign
, resultExponent
, work
.low());
384 case SpecialValueHandler::BothInfinity
:
385 return infinity(resultSign
);
387 case SpecialValueHandler::EitherNaN
:
388 return handler
.value();
390 case SpecialValueHandler::LHSIsInfinity
:
391 return rhs
.isZero() ? nan() : infinity(resultSign
);
393 case SpecialValueHandler::RHSIsInfinity
:
394 return lhs
.isZero() ? nan() : infinity(resultSign
);
397 ASSERT_NOT_REACHED();
401 Decimal
Decimal::operator/(const Decimal
& rhs
) const
403 const Decimal
& lhs
= *this;
404 const Sign lhsSign
= lhs
.sign();
405 const Sign rhsSign
= rhs
.sign();
406 const Sign resultSign
= lhsSign
== rhsSign
? Positive
: Negative
;
408 SpecialValueHandler
handler(lhs
, rhs
);
409 switch (handler
.handle()) {
410 case SpecialValueHandler::BothFinite
:
413 case SpecialValueHandler::BothInfinity
:
416 case SpecialValueHandler::EitherNaN
:
417 return handler
.value();
419 case SpecialValueHandler::LHSIsInfinity
:
420 return infinity(resultSign
);
422 case SpecialValueHandler::RHSIsInfinity
:
423 return zero(resultSign
);
426 ASSERT(lhs
.isFinite());
427 ASSERT(rhs
.isFinite());
430 return lhs
.isZero() ? nan() : infinity(resultSign
);
432 int resultExponent
= lhs
.exponent() - rhs
.exponent();
435 return Decimal(resultSign
, resultExponent
, 0);
437 uint64_t remainder
= lhs
.m_data
.coefficient();
438 const uint64_t divisor
= rhs
.m_data
.coefficient();
441 while (remainder
< divisor
&& result
< MaxCoefficient
/ 10) {
446 if (remainder
< divisor
)
448 uint64_t quotient
= remainder
/ divisor
;
449 if (result
> MaxCoefficient
- quotient
)
452 remainder
%= divisor
;
457 if (remainder
> divisor
/ 2)
460 return Decimal(resultSign
, resultExponent
, result
);
463 bool Decimal::operator==(const Decimal
& rhs
) const
465 if (isNaN() || rhs
.isNaN())
467 return m_data
== rhs
.m_data
|| compareTo(rhs
).isZero();
470 bool Decimal::operator!=(const Decimal
& rhs
) const
472 if (isNaN() || rhs
.isNaN())
474 if (m_data
== rhs
.m_data
)
476 const Decimal result
= compareTo(rhs
);
479 return !result
.isZero();
482 bool Decimal::operator<(const Decimal
& rhs
) const
484 const Decimal result
= compareTo(rhs
);
487 return !result
.isZero() && result
.isNegative();
490 bool Decimal::operator<=(const Decimal
& rhs
) const
492 if (isNaN() || rhs
.isNaN())
494 if (m_data
== rhs
.m_data
)
496 const Decimal result
= compareTo(rhs
);
499 return result
.isZero() || result
.isNegative();
502 bool Decimal::operator>(const Decimal
& rhs
) const
504 const Decimal result
= compareTo(rhs
);
507 return !result
.isZero() && result
.isPositive();
510 bool Decimal::operator>=(const Decimal
& rhs
) const
512 if (isNaN() || rhs
.isNaN())
514 if (m_data
== rhs
.m_data
)
516 const Decimal result
= compareTo(rhs
);
519 return result
.isZero() || !result
.isNegative();
522 Decimal
Decimal::abs() const
524 Decimal
result(*this);
525 result
.m_data
.setSign(Positive
);
529 Decimal::AlignedOperands
Decimal::alignOperands(const Decimal
& lhs
, const Decimal
& rhs
)
531 ASSERT(lhs
.isFinite());
532 ASSERT(rhs
.isFinite());
534 const int lhsExponent
= lhs
.exponent();
535 const int rhsExponent
= rhs
.exponent();
536 int exponent
= std::min(lhsExponent
, rhsExponent
);
537 uint64_t lhsCoefficient
= lhs
.m_data
.coefficient();
538 uint64_t rhsCoefficient
= rhs
.m_data
.coefficient();
540 if (lhsExponent
> rhsExponent
) {
541 const int numberOfLHSDigits
= countDigits(lhsCoefficient
);
542 if (numberOfLHSDigits
) {
543 const int lhsShiftAmount
= lhsExponent
- rhsExponent
;
544 const int overflow
= numberOfLHSDigits
+ lhsShiftAmount
- Precision
;
546 lhsCoefficient
= scaleUp(lhsCoefficient
, lhsShiftAmount
);
548 lhsCoefficient
= scaleUp(lhsCoefficient
, lhsShiftAmount
- overflow
);
549 rhsCoefficient
= scaleDown(rhsCoefficient
, overflow
);
550 exponent
+= overflow
;
554 } else if (lhsExponent
< rhsExponent
) {
555 const int numberOfRHSDigits
= countDigits(rhsCoefficient
);
556 if (numberOfRHSDigits
) {
557 const int rhsShiftAmount
= rhsExponent
- lhsExponent
;
558 const int overflow
= numberOfRHSDigits
+ rhsShiftAmount
- Precision
;
560 rhsCoefficient
= scaleUp(rhsCoefficient
, rhsShiftAmount
);
562 rhsCoefficient
= scaleUp(rhsCoefficient
, rhsShiftAmount
- overflow
);
563 lhsCoefficient
= scaleDown(lhsCoefficient
, overflow
);
564 exponent
+= overflow
;
569 AlignedOperands alignedOperands
;
570 alignedOperands
.exponent
= exponent
;
571 alignedOperands
.lhsCoefficient
= lhsCoefficient
;
572 alignedOperands
.rhsCoefficient
= rhsCoefficient
;
573 return alignedOperands
;
576 static bool isMultiplePowersOfTen(uint64_t coefficient
, int n
)
578 return !coefficient
|| !(coefficient
% scaleUp(1, n
));
581 // Round toward positive infinity.
582 Decimal
Decimal::ceil() const
590 uint64_t result
= m_data
.coefficient();
591 const int numberOfDigits
= countDigits(result
);
592 const int numberOfDropDigits
= -exponent();
593 if (numberOfDigits
<= numberOfDropDigits
)
594 return isPositive() ? Decimal(1) : zero(Positive
);
596 result
= scaleDown(result
, numberOfDropDigits
);
597 if (isPositive() && !isMultiplePowersOfTen(m_data
.coefficient(), numberOfDropDigits
))
599 return Decimal(sign(), 0, result
);
602 Decimal
Decimal::compareTo(const Decimal
& rhs
) const
604 const Decimal
result(*this - rhs
);
605 switch (result
.m_data
.formatClass()) {
606 case EncodedData::ClassInfinity
:
607 return result
.isNegative() ? Decimal(-1) : Decimal(1);
609 case EncodedData::ClassNaN
:
610 case EncodedData::ClassNormal
:
613 case EncodedData::ClassZero
:
614 return zero(Positive
);
617 ASSERT_NOT_REACHED();
622 // Round toward negative infinity.
623 Decimal
Decimal::floor() const
631 uint64_t result
= m_data
.coefficient();
632 const int numberOfDigits
= countDigits(result
);
633 const int numberOfDropDigits
= -exponent();
634 if (numberOfDigits
< numberOfDropDigits
)
635 return isPositive() ? zero(Positive
) : Decimal(-1);
637 result
= scaleDown(result
, numberOfDropDigits
);
638 if (isNegative() && !isMultiplePowersOfTen(m_data
.coefficient(), numberOfDropDigits
))
640 return Decimal(sign(), 0, result
);
643 Decimal
Decimal::fromDouble(double doubleValue
)
645 if (std::isfinite(doubleValue
))
646 return fromString(mozToString(doubleValue
));
648 if (std::isinf(doubleValue
))
649 return infinity(doubleValue
< 0 ? Negative
: Positive
);
654 Decimal
Decimal::fromString(const String
& str
)
657 Sign exponentSign
= Positive
;
658 int numberOfDigits
= 0;
659 int numberOfDigitsAfterDot
= 0;
660 int numberOfExtraDigits
= 0;
661 Sign sign
= Positive
;
673 } state
= StateStart
;
675 #define HandleCharAndBreak(expected, nextState) \
676 if (ch == expected) { \
681 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
682 if (ch == expected1 || ch == expected2) { \
687 uint64_t accumulator
= 0;
688 for (unsigned index
= 0; index
< str
.length(); ++index
) {
689 const int ch
= str
[index
];
692 if (ch
>= '0' && ch
<= '9') {
693 if (numberOfDigits
< Precision
) {
696 accumulator
+= ch
- '0';
698 ++numberOfExtraDigits
;
703 HandleCharAndBreak('.', StateDot
);
704 HandleTwoCharsAndBreak('E', 'e', StateE
);
709 if (ch
>= '0' && ch
<= '9') {
710 if (numberOfDigits
< Precision
) {
712 ++numberOfDigitsAfterDot
;
714 accumulator
+= ch
- '0';
716 state
= StateDotDigit
;
720 HandleTwoCharsAndBreak('E', 'e', StateE
);
725 exponentSign
= Positive
;
731 exponentSign
= Negative
;
736 if (ch
>= '0' && ch
<= '9') {
745 if (ch
>= '0' && ch
<= '9') {
747 exponent
+= ch
- '0';
748 if (exponent
> ExponentMax
+ Precision
) {
750 return exponentSign
== Negative
? zero(Positive
) : infinity(sign
);
760 if (ch
>= '0' && ch
<= '9') {
769 if (ch
>= '1' && ch
<= '9') {
770 accumulator
= ch
- '0';
776 HandleCharAndBreak('0', StateZero
);
780 if (ch
>= '1' && ch
<= '9') {
781 accumulator
= ch
- '0';
799 HandleCharAndBreak('0', StateZero
);
800 HandleCharAndBreak('.', StateDot
);
807 if (ch
>= '1' && ch
<= '9') {
808 accumulator
= ch
- '0';
814 HandleCharAndBreak('.', StateDot
);
815 HandleTwoCharsAndBreak('E', 'e', StateE
);
819 ASSERT_NOT_REACHED();
824 if (state
== StateZero
)
827 if (state
== StateDigit
|| state
== StateEDigit
|| state
== StateDotDigit
) {
828 int resultExponent
= exponent
* (exponentSign
== Negative
? -1 : 1) - numberOfDigitsAfterDot
+ numberOfExtraDigits
;
829 if (resultExponent
< ExponentMin
)
830 return zero(Positive
);
832 const int overflow
= resultExponent
- ExponentMax
+ 1;
834 if (overflow
+ numberOfDigits
- numberOfDigitsAfterDot
> Precision
)
835 return infinity(sign
);
836 accumulator
= scaleUp(accumulator
, overflow
);
837 resultExponent
-= overflow
;
840 return Decimal(sign
, resultExponent
, accumulator
);
846 Decimal
Decimal::infinity(const Sign sign
)
848 return Decimal(EncodedData(sign
, EncodedData::ClassInfinity
));
851 Decimal
Decimal::remainder(const Decimal
& rhs
) const
853 const Decimal quotient
= *this / rhs
;
854 return quotient
.isSpecial() ? quotient
: *this - (quotient
.isNegative() ? quotient
.ceil() : quotient
.floor()) * rhs
;
857 Decimal
Decimal::round() const
865 uint64_t result
= m_data
.coefficient();
866 const int numberOfDigits
= countDigits(result
);
867 const int numberOfDropDigits
= -exponent();
868 if (numberOfDigits
< numberOfDropDigits
)
869 return zero(Positive
);
871 result
= scaleDown(result
, numberOfDropDigits
- 1);
872 if (result
% 10 >= 5)
875 return Decimal(sign(), 0, result
);
878 double Decimal::toDouble() const
882 const double doubleValue
= mozToDouble(toString(), &valid
);
883 return valid
? doubleValue
: std::numeric_limits
<double>::quiet_NaN();
887 return isNegative() ? -std::numeric_limits
<double>::infinity() : std::numeric_limits
<double>::infinity();
889 return std::numeric_limits
<double>::quiet_NaN();
892 String
Decimal::toString() const
894 switch (m_data
.formatClass()) {
895 case EncodedData::ClassInfinity
:
896 return sign() ? "-Infinity" : "Infinity";
898 case EncodedData::ClassNaN
:
901 case EncodedData::ClassNormal
:
902 case EncodedData::ClassZero
:
906 ASSERT_NOT_REACHED();
910 StringBuilder builder
;
914 int originalExponent
= exponent();
915 uint64_t coefficient
= m_data
.coefficient();
917 if (originalExponent
< 0) {
918 const int maxDigits
= DBL_DIG
;
919 uint64_t lastDigit
= 0;
920 while (countDigits(coefficient
) > maxDigits
) {
921 lastDigit
= coefficient
% 10;
929 while (originalExponent
< 0 && coefficient
&& !(coefficient
% 10)) {
935 const String digits
= mozToString(coefficient
);
936 int coefficientLength
= static_cast<int>(digits
.length());
937 const int adjustedExponent
= originalExponent
+ coefficientLength
- 1;
938 if (originalExponent
<= 0 && adjustedExponent
>= -6) {
939 if (!originalExponent
) {
940 builder
.append(digits
);
941 return builder
.toString();
944 if (adjustedExponent
>= 0) {
945 for (int i
= 0; i
< coefficientLength
; ++i
) {
946 builder
.append(digits
[i
]);
947 if (i
== adjustedExponent
)
950 return builder
.toString();
953 builder
.appendLiteral("0.");
954 for (int i
= adjustedExponent
+ 1; i
< 0; ++i
)
957 builder
.append(digits
);
960 builder
.append(digits
[0]);
961 while (coefficientLength
>= 2 && digits
[coefficientLength
- 1] == '0')
963 if (coefficientLength
>= 2) {
965 for (int i
= 1; i
< coefficientLength
; ++i
)
966 builder
.append(digits
[i
]);
969 if (adjustedExponent
) {
970 builder
.append(adjustedExponent
< 0 ? "e" : "e+");
971 builder
.appendNumber(adjustedExponent
);
974 return builder
.toString();
977 Decimal
Decimal::zero(Sign sign
)
979 return Decimal(EncodedData(sign
, EncodedData::ClassZero
));
984 // Implementation of DoubleConversion.h:
988 Maybe
<double> StringToDouble(Span
<const char> aStringSpan
) {
990 double result
= mozToDouble(aStringSpan
, &valid
);
991 return valid
? Some(result
) : Nothing();