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();
491 while (result < MaxCoefficient / 100) {
492 while (remainder < divisor) {
497 result += remainder / divisor;
498 remainder %= divisor;
503 if (remainder > divisor / 2)
506 return Decimal(resultSign, resultExponent, result);
509 bool Decimal::operator==(const Decimal& rhs) const
511 return m_data == rhs.m_data || compareTo(rhs).isZero();
514 bool Decimal::operator!=(const Decimal& rhs) const
516 if (m_data == rhs.m_data)
518 const Decimal result = compareTo(rhs);
521 return !result.isZero();
524 bool Decimal::operator<(const Decimal& rhs) const
526 const Decimal result = compareTo(rhs);
529 return !result.isZero() && result.isNegative();
532 bool Decimal::operator<=(const Decimal& rhs) const
534 if (m_data == rhs.m_data)
536 const Decimal result = compareTo(rhs);
539 return result.isZero() || result.isNegative();
542 bool Decimal::operator>(const Decimal& rhs) const
544 const Decimal result = compareTo(rhs);
547 return !result.isZero() && result.isPositive();
550 bool Decimal::operator>=(const Decimal& rhs) const
552 if (m_data == rhs.m_data)
554 const Decimal result = compareTo(rhs);
557 return result.isZero() || !result.isNegative();
560 Decimal Decimal::abs() const
562 Decimal result(*this);
563 result.m_data.setSign(Positive);
567 Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs)
569 ASSERT(lhs.isFinite());
570 ASSERT(rhs.isFinite());
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();
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;
584 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount);
586 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow);
587 rhsCoefficient = scaleDown(rhsCoefficient, overflow);
588 exponent += overflow;
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;
598 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount);
600 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow);
601 lhsCoefficient = scaleDown(lhsCoefficient, overflow);
602 exponent += overflow;
607 AlignedOperands alignedOperands;
608 alignedOperands.exponent = exponent;
609 alignedOperands.lhsCoefficient = lhsCoefficient;
610 alignedOperands.rhsCoefficient = rhsCoefficient;
611 return alignedOperands;
614 static bool isMultiplePowersOfTen(uint64_t coefficient, int n)
616 return !coefficient || !(coefficient % scaleUp(1, n));
619 // Round toward positive infinity.
620 Decimal Decimal::ceil() const
628 uint64_t result = m_data.coefficient();
629 const int numberOfDigits = countDigits(result);
630 const int numberOfDropDigits = -exponent();
631 if (numberOfDigits < numberOfDropDigits)
632 return isPositive() ? Decimal(1) : zero(Positive);
634 result = scaleDown(result, numberOfDropDigits);
635 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits))
637 return Decimal(sign(), 0, result);
640 Decimal Decimal::compareTo(const Decimal& rhs) const
642 const Decimal result(*this - rhs);
643 switch (result.m_data.formatClass()) {
644 case EncodedData::ClassInfinity:
645 return result.isNegative() ? Decimal(-1) : Decimal(1);
647 case EncodedData::ClassNaN:
648 case EncodedData::ClassNormal:
651 case EncodedData::ClassZero:
652 return zero(Positive);
655 ASSERT_NOT_REACHED();
660 // Round toward negative infinity.
661 Decimal Decimal::floor() const
669 uint64_t result = m_data.coefficient();
670 const int numberOfDigits = countDigits(result);
671 const int numberOfDropDigits = -exponent();
672 if (numberOfDigits < numberOfDropDigits)
673 return isPositive() ? zero(Positive) : Decimal(-1);
675 result = scaleDown(result, numberOfDropDigits);
676 if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits))
678 return Decimal(sign(), 0, result);
681 Decimal Decimal::fromDouble(double doubleValue)
683 if (std::isfinite(doubleValue))
684 return fromString(String::numberToStringECMAScript(doubleValue));
686 if (std::isinf(doubleValue))
687 return infinity(doubleValue < 0 ? Negative : Positive);
692 Decimal Decimal::fromString(const String& str)
695 Sign exponentSign = Positive;
696 int numberOfDigits = 0;
697 int numberOfDigitsAfterDot = 0;
698 int numberOfExtraDigits = 0;
699 Sign sign = Positive;
711 } state = StateStart;
713 #define HandleCharAndBreak(expected, nextState) \
714 if (ch == expected) { \
719 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
720 if (ch == expected1 || ch == expected2) { \
725 uint64_t accumulator = 0;
726 for (unsigned index = 0; index < str.length(); ++index) {
727 const int ch = str[index];
730 if (ch >= '0' && ch <= '9') {
731 if (numberOfDigits < Precision) {
734 accumulator += ch - '0';
736 ++numberOfExtraDigits;
741 HandleCharAndBreak('.', StateDot);
742 HandleTwoCharsAndBreak('E', 'e', StateE);
747 if (ch >= '0' && ch <= '9') {
748 if (numberOfDigits < Precision) {
750 ++numberOfDigitsAfterDot;
752 accumulator += ch - '0';
754 state = StateDotDigit;
758 HandleTwoCharsAndBreak('E', 'e', StateE);
763 exponentSign = Positive;
769 exponentSign = Negative;
774 if (ch >= '0' && ch <= '9') {
783 if (ch >= '0' && ch <= '9') {
785 exponent += ch - '0';
786 if (exponent > ExponentMax + Precision) {
788 return exponentSign == Negative ? zero(Positive) : infinity(sign);
798 if (ch >= '0' && ch <= '9') {
807 if (ch >= '1' && ch <= '9') {
808 accumulator = ch - '0';
814 HandleCharAndBreak('0', StateZero);
818 if (ch >= '1' && ch <= '9') {
819 accumulator = ch - '0';
837 HandleCharAndBreak('0', StateZero);
838 HandleCharAndBreak('.', StateDot);
845 if (ch >= '1' && ch <= '9') {
846 accumulator = ch - '0';
852 HandleCharAndBreak('.', StateDot);
853 HandleTwoCharsAndBreak('E', 'e', StateE);
857 ASSERT_NOT_REACHED();
862 if (state == StateZero)
865 if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
866 int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
867 if (resultExponent < ExponentMin)
868 return zero(Positive);
870 const int overflow = resultExponent - ExponentMax + 1;
872 if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision)
873 return infinity(sign);
874 accumulator = scaleUp(accumulator, overflow);
875 resultExponent -= overflow;
878 return Decimal(sign, resultExponent, accumulator);
884 Decimal Decimal::infinity(const Sign sign)
886 return Decimal(EncodedData(sign, EncodedData::ClassInfinity));
889 Decimal Decimal::nan()
891 return Decimal(EncodedData(Positive, EncodedData::ClassNaN));
894 Decimal Decimal::remainder(const Decimal& rhs) const
896 const Decimal quotient = *this / rhs;
897 return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceil() : quotient.floor()) * rhs;
900 Decimal Decimal::round() const
908 uint64_t result = m_data.coefficient();
909 const int numberOfDigits = countDigits(result);
910 const int numberOfDropDigits = -exponent();
911 if (numberOfDigits < numberOfDropDigits)
912 return zero(Positive);
914 result = scaleDown(result, numberOfDropDigits - 1);
915 if (result % 10 >= 5)
918 return Decimal(sign(), 0, result);
921 double Decimal::toDouble() const
925 const double doubleValue = toString().toDouble(&valid);
926 return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN();
930 return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
932 return std::numeric_limits<double>::quiet_NaN();
935 String Decimal::toString() const
937 switch (m_data.formatClass()) {
938 case EncodedData::ClassInfinity:
939 return sign() ? "-Infinity" : "Infinity";
941 case EncodedData::ClassNaN:
944 case EncodedData::ClassNormal:
945 case EncodedData::ClassZero:
949 ASSERT_NOT_REACHED();
953 StringBuilder builder;
957 int originalExponent = exponent();
958 uint64_t coefficient = m_data.coefficient();
960 if (originalExponent < 0) {
961 const int maxDigits = DBL_DIG;
962 uint64_t lastDigit = 0;
963 while (countDigits(coefficient) > maxDigits) {
964 lastDigit = coefficient % 10;
972 while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
978 const String digits = String::number(coefficient);
979 int coefficientLength = static_cast<int>(digits.length());
980 const int adjustedExponent = originalExponent + coefficientLength - 1;
981 if (originalExponent <= 0 && adjustedExponent >= -6) {
982 if (!originalExponent) {
983 builder.append(digits);
984 return builder.toString();
987 if (adjustedExponent >= 0) {
988 for (int i = 0; i < coefficientLength; ++i) {
989 builder.append(digits[i]);
990 if (i == adjustedExponent)
993 return builder.toString();
996 builder.appendLiteral("0.");
997 for (int i = adjustedExponent + 1; i < 0; ++i)
1000 builder.append(digits);
1003 builder.append(digits[0]);
1004 while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0')
1005 --coefficientLength;
1006 if (coefficientLength >= 2) {
1007 builder.append('.');
1008 for (int i = 1; i < coefficientLength; ++i)
1009 builder.append(digits[i]);
1012 if (adjustedExponent) {
1013 builder.append(adjustedExponent < 0 ? "e" : "e+");
1014 builder.appendNumber(adjustedExponent);
1017 return builder.toString();
1020 Decimal Decimal::zero(Sign sign)
1022 return Decimal(EncodedData(sign, EncodedData::ClassZero));
1025 } // namespace blink