Decimal.cpp (27643B)
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 "Decimal.h" 32 #include "moz-decimal-utils.h" 33 #include "DoubleConversion.h" 34 35 using namespace moz_decimal_utils; 36 37 #include <algorithm> 38 #include <float.h> 39 40 namespace blink { 41 42 namespace DecimalPrivate { 43 44 // This class handles Decimal special values. 45 class SpecialValueHandler { 46 STACK_ALLOCATED(); 47 WTF_MAKE_NONCOPYABLE(SpecialValueHandler); 48 public: 49 enum HandleResult { 50 BothFinite, 51 BothInfinity, 52 EitherNaN, 53 LHSIsInfinity, 54 RHSIsInfinity, 55 }; 56 57 SpecialValueHandler(const Decimal& lhs, const Decimal& rhs); 58 HandleResult handle(); 59 Decimal value() const; 60 61 private: 62 enum Result { 63 ResultIsLHS, 64 ResultIsRHS, 65 ResultIsUnknown, 66 }; 67 68 const Decimal& m_lhs; 69 const Decimal& m_rhs; 70 Result m_result; 71 }; 72 73 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs) 74 : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown) 75 { 76 } 77 78 SpecialValueHandler::HandleResult SpecialValueHandler::handle() 79 { 80 if (m_lhs.isFinite() && m_rhs.isFinite()) 81 return BothFinite; 82 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; 87 return EitherNaN; 88 } 89 90 if (rhsClass == Decimal::EncodedData::ClassNaN) { 91 m_result = ResultIsRHS; 92 return EitherNaN; 93 } 94 95 if (lhsClass == Decimal::EncodedData::ClassInfinity) 96 return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity; 97 98 if (rhsClass == Decimal::EncodedData::ClassInfinity) 99 return RHSIsInfinity; 100 101 ASSERT_NOT_REACHED(); 102 return BothFinite; 103 } 104 105 Decimal SpecialValueHandler::value() const 106 { 107 switch (m_result) { 108 case ResultIsLHS: 109 return m_lhs; 110 case ResultIsRHS: 111 return m_rhs; 112 case ResultIsUnknown: 113 default: 114 ASSERT_NOT_REACHED(); 115 return m_lhs; 116 } 117 } 118 119 // This class is used for 128 bit unsigned integer arithmetic. 120 class UInt128 { 121 public: 122 UInt128(uint64_t low, uint64_t high) 123 : m_high(high), m_low(low) 124 { 125 } 126 127 UInt128& operator/=(uint32_t); 128 129 uint64_t high() const { return m_high; } 130 uint64_t low() const { return m_low; } 131 132 static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); } 133 134 private: 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); } 138 139 static uint64_t multiplyHigh(uint64_t, uint64_t); 140 141 uint64_t m_high; 142 uint64_t m_low; 143 }; 144 145 UInt128& UInt128::operator/=(const uint32_t divisor) 146 { 147 ASSERT(divisor); 148 149 if (!m_high) { 150 m_low /= divisor; 151 return *this; 152 } 153 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); 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 m_low = makeUInt64(quotient[0], quotient[1]); 168 m_high = makeUInt64(quotient[2], quotient[3]); 169 return *this; 170 } 171 172 // Returns high 64bit of 128bit product. 173 uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v) 174 { 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)); 181 } 182 183 static int countDigits(uint64_t x) 184 { 185 int numberOfDigits = 0; 186 for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) { 187 ++numberOfDigits; 188 if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10) 189 break; 190 } 191 return numberOfDigits; 192 } 193 194 static uint64_t scaleDown(uint64_t x, int n) 195 { 196 ASSERT(n >= 0); 197 while (n > 0 && x) { 198 x /= 10; 199 --n; 200 } 201 return x; 202 } 203 204 static uint64_t scaleUp(uint64_t x, int n) 205 { 206 ASSERT(n >= 0); 207 ASSERT(n <= Precision); 208 209 uint64_t y = 1; 210 uint64_t z = 10; 211 for (;;) { 212 if (n & 1) 213 y = y * z; 214 215 n >>= 1; 216 if (!n) 217 return x * y; 218 219 z = z * z; 220 } 221 } 222 223 } // namespace DecimalPrivate 224 225 using namespace DecimalPrivate; 226 227 bool Decimal::EncodedData::operator==(const EncodedData& another) const 228 { 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; 233 } 234 235 236 Decimal::Decimal(int32_t i32) 237 : Decimal(DecimalLiteral{i32}) {} 238 239 Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient) 240 : m_data(sign, coefficient ? exponent : 0, coefficient) {} 241 242 Decimal::Decimal(const Decimal& other) 243 : m_data(other.m_data) 244 { 245 } 246 247 Decimal& Decimal::operator=(const Decimal& other) 248 { 249 m_data = other.m_data; 250 return *this; 251 } 252 253 Decimal& Decimal::operator+=(const Decimal& other) 254 { 255 m_data = (*this + other).m_data; 256 return *this; 257 } 258 259 Decimal& Decimal::operator-=(const Decimal& other) 260 { 261 m_data = (*this - other).m_data; 262 return *this; 263 } 264 265 Decimal& Decimal::operator*=(const Decimal& other) 266 { 267 m_data = (*this * other).m_data; 268 return *this; 269 } 270 271 Decimal& Decimal::operator/=(const Decimal& other) 272 { 273 m_data = (*this / other).m_data; 274 return *this; 275 } 276 277 Decimal Decimal::operator-() const 278 { 279 if (isNaN()) 280 return *this; 281 282 Decimal result(*this); 283 result.m_data.setSign(invertSign(m_data.sign())); 284 return result; 285 } 286 287 Decimal Decimal::operator+(const Decimal& rhs) const 288 { 289 const Decimal& lhs = *this; 290 const Sign lhsSign = lhs.sign(); 291 const Sign rhsSign = rhs.sign(); 292 293 SpecialValueHandler handler(lhs, rhs); 294 switch (handler.handle()) { 295 case SpecialValueHandler::BothFinite: 296 break; 297 298 case SpecialValueHandler::BothInfinity: 299 return lhsSign == rhsSign ? lhs : nan(); 300 301 case SpecialValueHandler::EitherNaN: 302 return handler.value(); 303 304 case SpecialValueHandler::LHSIsInfinity: 305 return lhs; 306 307 case SpecialValueHandler::RHSIsInfinity: 308 return rhs; 309 } 310 311 const AlignedOperands alignedOperands = alignOperands(lhs, rhs); 312 313 const uint64_t result = lhsSign == rhsSign 314 ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient 315 : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient; 316 317 if (lhsSign == Negative && rhsSign == Positive && !result) 318 return Decimal(Positive, alignedOperands.exponent, 0); 319 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)); 323 } 324 325 Decimal Decimal::operator-(const Decimal& rhs) const 326 { 327 const Decimal& lhs = *this; 328 const Sign lhsSign = lhs.sign(); 329 const Sign rhsSign = rhs.sign(); 330 331 SpecialValueHandler handler(lhs, rhs); 332 switch (handler.handle()) { 333 case SpecialValueHandler::BothFinite: 334 break; 335 336 case SpecialValueHandler::BothInfinity: 337 return lhsSign == rhsSign ? nan() : lhs; 338 339 case SpecialValueHandler::EitherNaN: 340 return handler.value(); 341 342 case SpecialValueHandler::LHSIsInfinity: 343 return lhs; 344 345 case SpecialValueHandler::RHSIsInfinity: 346 return infinity(invertSign(rhsSign)); 347 } 348 349 const AlignedOperands alignedOperands = alignOperands(lhs, rhs); 350 351 const uint64_t result = lhsSign == rhsSign 352 ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient 353 : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient; 354 355 if (lhsSign == Negative && rhsSign == Negative && !result) 356 return Decimal(Positive, alignedOperands.exponent, 0); 357 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)); 361 } 362 363 Decimal Decimal::operator*(const Decimal& rhs) const 364 { 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; 369 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()) { 378 work /= 10; 379 ++resultExponent; 380 } 381 return Decimal(resultSign, resultExponent, work.low()); 382 } 383 384 case SpecialValueHandler::BothInfinity: 385 return infinity(resultSign); 386 387 case SpecialValueHandler::EitherNaN: 388 return handler.value(); 389 390 case SpecialValueHandler::LHSIsInfinity: 391 return rhs.isZero() ? nan() : infinity(resultSign); 392 393 case SpecialValueHandler::RHSIsInfinity: 394 return lhs.isZero() ? nan() : infinity(resultSign); 395 } 396 397 ASSERT_NOT_REACHED(); 398 return nan(); 399 } 400 401 Decimal Decimal::operator/(const Decimal& rhs) const 402 { 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; 407 408 SpecialValueHandler handler(lhs, rhs); 409 switch (handler.handle()) { 410 case SpecialValueHandler::BothFinite: 411 break; 412 413 case SpecialValueHandler::BothInfinity: 414 return nan(); 415 416 case SpecialValueHandler::EitherNaN: 417 return handler.value(); 418 419 case SpecialValueHandler::LHSIsInfinity: 420 return infinity(resultSign); 421 422 case SpecialValueHandler::RHSIsInfinity: 423 return zero(resultSign); 424 } 425 426 ASSERT(lhs.isFinite()); 427 ASSERT(rhs.isFinite()); 428 429 if (rhs.isZero()) 430 return lhs.isZero() ? nan() : infinity(resultSign); 431 432 int resultExponent = lhs.exponent() - rhs.exponent(); 433 434 if (lhs.isZero()) 435 return Decimal(resultSign, resultExponent, 0); 436 437 uint64_t remainder = lhs.m_data.coefficient(); 438 const uint64_t divisor = rhs.m_data.coefficient(); 439 uint64_t result = 0; 440 for (;;) { 441 while (remainder < divisor && result < MaxCoefficient / 10) { 442 remainder *= 10; 443 result *= 10; 444 --resultExponent; 445 } 446 if (remainder < divisor) 447 break; 448 uint64_t quotient = remainder / divisor; 449 if (result > MaxCoefficient - quotient) 450 break; 451 result += quotient; 452 remainder %= divisor; 453 if (!remainder) 454 break; 455 } 456 457 if (remainder > divisor / 2) 458 ++result; 459 460 return Decimal(resultSign, resultExponent, result); 461 } 462 463 bool Decimal::operator==(const Decimal& rhs) const 464 { 465 if (isNaN() || rhs.isNaN()) 466 return false; 467 return m_data == rhs.m_data || compareTo(rhs).isZero(); 468 } 469 470 bool Decimal::operator!=(const Decimal& rhs) const 471 { 472 if (isNaN() || rhs.isNaN()) 473 return true; 474 if (m_data == rhs.m_data) 475 return false; 476 const Decimal result = compareTo(rhs); 477 if (result.isNaN()) 478 return false; 479 return !result.isZero(); 480 } 481 482 bool Decimal::operator<(const Decimal& rhs) const 483 { 484 const Decimal result = compareTo(rhs); 485 if (result.isNaN()) 486 return false; 487 return !result.isZero() && result.isNegative(); 488 } 489 490 bool Decimal::operator<=(const Decimal& rhs) const 491 { 492 if (isNaN() || rhs.isNaN()) 493 return false; 494 if (m_data == rhs.m_data) 495 return true; 496 const Decimal result = compareTo(rhs); 497 if (result.isNaN()) 498 return false; 499 return result.isZero() || result.isNegative(); 500 } 501 502 bool Decimal::operator>(const Decimal& rhs) const 503 { 504 const Decimal result = compareTo(rhs); 505 if (result.isNaN()) 506 return false; 507 return !result.isZero() && result.isPositive(); 508 } 509 510 bool Decimal::operator>=(const Decimal& rhs) const 511 { 512 if (isNaN() || rhs.isNaN()) 513 return false; 514 if (m_data == rhs.m_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 522 Decimal Decimal::abs() const 523 { 524 Decimal result(*this); 525 result.m_data.setSign(Positive); 526 return result; 527 } 528 529 Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs) 530 { 531 ASSERT(lhs.isFinite()); 532 ASSERT(rhs.isFinite()); 533 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(); 539 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; 545 if (overflow <= 0) { 546 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount); 547 } else { 548 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow); 549 rhsCoefficient = scaleDown(rhsCoefficient, overflow); 550 exponent += overflow; 551 } 552 } 553 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; 559 if (overflow <= 0) { 560 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount); 561 } else { 562 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow); 563 lhsCoefficient = scaleDown(lhsCoefficient, overflow); 564 exponent += overflow; 565 } 566 } 567 } 568 569 AlignedOperands alignedOperands; 570 alignedOperands.exponent = exponent; 571 alignedOperands.lhsCoefficient = lhsCoefficient; 572 alignedOperands.rhsCoefficient = rhsCoefficient; 573 return alignedOperands; 574 } 575 576 static bool isMultiplePowersOfTen(uint64_t coefficient, int n) 577 { 578 return !coefficient || !(coefficient % scaleUp(1, n)); 579 } 580 581 // Round toward positive infinity. 582 Decimal Decimal::ceil() const 583 { 584 if (isSpecial()) 585 return *this; 586 587 if (exponent() >= 0) 588 return *this; 589 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); 595 596 result = scaleDown(result, numberOfDropDigits); 597 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits)) 598 ++result; 599 return Decimal(sign(), 0, result); 600 } 601 602 Decimal Decimal::compareTo(const Decimal& rhs) const 603 { 604 const Decimal result(*this - rhs); 605 switch (result.m_data.formatClass()) { 606 case EncodedData::ClassInfinity: 607 return result.isNegative() ? Decimal(-1) : Decimal(1); 608 609 case EncodedData::ClassNaN: 610 case EncodedData::ClassNormal: 611 return result; 612 613 case EncodedData::ClassZero: 614 return zero(Positive); 615 616 default: 617 ASSERT_NOT_REACHED(); 618 return nan(); 619 } 620 } 621 622 // Round toward negative infinity. 623 Decimal Decimal::floor() const 624 { 625 if (isSpecial()) 626 return *this; 627 628 if (exponent() >= 0) 629 return *this; 630 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); 636 637 result = scaleDown(result, numberOfDropDigits); 638 if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits)) 639 ++result; 640 return Decimal(sign(), 0, result); 641 } 642 643 Decimal Decimal::fromDouble(double doubleValue) 644 { 645 if (std::isfinite(doubleValue)) 646 return fromString(mozToString(doubleValue)); 647 648 if (std::isinf(doubleValue)) 649 return infinity(doubleValue < 0 ? Negative : Positive); 650 651 return nan(); 652 } 653 654 Decimal Decimal::fromString(const String& str) 655 { 656 int exponent = 0; 657 Sign exponentSign = Positive; 658 int numberOfDigits = 0; 659 int numberOfDigitsAfterDot = 0; 660 int numberOfExtraDigits = 0; 661 Sign sign = Positive; 662 663 enum { 664 StateDigit, 665 StateDot, 666 StateDotDigit, 667 StateE, 668 StateEDigit, 669 StateESign, 670 StateSign, 671 StateStart, 672 StateZero, 673 } state = StateStart; 674 675 #define HandleCharAndBreak(expected, nextState) \ 676 if (ch == expected) { \ 677 state = nextState; \ 678 break; \ 679 } 680 681 #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \ 682 if (ch == expected1 || ch == expected2) { \ 683 state = nextState; \ 684 break; \ 685 } 686 687 uint64_t accumulator = 0; 688 for (unsigned index = 0; index < str.length(); ++index) { 689 const int ch = str[index]; 690 switch (state) { 691 case StateDigit: 692 if (ch >= '0' && ch <= '9') { 693 if (numberOfDigits < Precision) { 694 ++numberOfDigits; 695 accumulator *= 10; 696 accumulator += ch - '0'; 697 } else { 698 ++numberOfExtraDigits; 699 } 700 break; 701 } 702 703 HandleCharAndBreak('.', StateDot); 704 HandleTwoCharsAndBreak('E', 'e', StateE); 705 return nan(); 706 707 case StateDot: 708 case StateDotDigit: 709 if (ch >= '0' && ch <= '9') { 710 if (numberOfDigits < Precision) { 711 ++numberOfDigits; 712 ++numberOfDigitsAfterDot; 713 accumulator *= 10; 714 accumulator += ch - '0'; 715 } 716 state = StateDotDigit; 717 break; 718 } 719 720 HandleTwoCharsAndBreak('E', 'e', StateE); 721 return nan(); 722 723 case StateE: 724 if (ch == '+') { 725 exponentSign = Positive; 726 state = StateESign; 727 break; 728 } 729 730 if (ch == '-') { 731 exponentSign = Negative; 732 state = StateESign; 733 break; 734 } 735 736 if (ch >= '0' && ch <= '9') { 737 exponent = ch - '0'; 738 state = StateEDigit; 739 break; 740 } 741 742 return nan(); 743 744 case StateEDigit: 745 if (ch >= '0' && ch <= '9') { 746 exponent *= 10; 747 exponent += ch - '0'; 748 if (exponent > ExponentMax + Precision) { 749 if (accumulator) 750 return exponentSign == Negative ? zero(Positive) : infinity(sign); 751 return zero(sign); 752 } 753 state = StateEDigit; 754 break; 755 } 756 757 return nan(); 758 759 case StateESign: 760 if (ch >= '0' && ch <= '9') { 761 exponent = ch - '0'; 762 state = StateEDigit; 763 break; 764 } 765 766 return nan(); 767 768 case StateSign: 769 if (ch >= '1' && ch <= '9') { 770 accumulator = ch - '0'; 771 numberOfDigits = 1; 772 state = StateDigit; 773 break; 774 } 775 776 HandleCharAndBreak('0', StateZero); 777 return nan(); 778 779 case StateStart: 780 if (ch >= '1' && ch <= '9') { 781 accumulator = ch - '0'; 782 numberOfDigits = 1; 783 state = StateDigit; 784 break; 785 } 786 787 if (ch == '-') { 788 sign = Negative; 789 state = StateSign; 790 break; 791 } 792 793 if (ch == '+') { 794 sign = Positive; 795 state = StateSign; 796 break; 797 } 798 799 HandleCharAndBreak('0', StateZero); 800 HandleCharAndBreak('.', StateDot); 801 return nan(); 802 803 case StateZero: 804 if (ch == '0') 805 break; 806 807 if (ch >= '1' && ch <= '9') { 808 accumulator = ch - '0'; 809 numberOfDigits = 1; 810 state = StateDigit; 811 break; 812 } 813 814 HandleCharAndBreak('.', StateDot); 815 HandleTwoCharsAndBreak('E', 'e', StateE); 816 return nan(); 817 818 default: 819 ASSERT_NOT_REACHED(); 820 return nan(); 821 } 822 } 823 824 if (state == StateZero) 825 return zero(sign); 826 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); 831 832 const int overflow = resultExponent - ExponentMax + 1; 833 if (overflow > 0) { 834 if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision) 835 return infinity(sign); 836 accumulator = scaleUp(accumulator, overflow); 837 resultExponent -= overflow; 838 } 839 840 return Decimal(sign, resultExponent, accumulator); 841 } 842 843 return nan(); 844 } 845 846 Decimal Decimal::infinity(const Sign sign) 847 { 848 return Decimal(EncodedData(sign, EncodedData::ClassInfinity)); 849 } 850 851 Decimal Decimal::remainder(const Decimal& rhs) const 852 { 853 const Decimal quotient = *this / rhs; 854 return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceil() : quotient.floor()) * rhs; 855 } 856 857 Decimal Decimal::round() const 858 { 859 if (isSpecial()) 860 return *this; 861 862 if (exponent() >= 0) 863 return *this; 864 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); 870 871 result = scaleDown(result, numberOfDropDigits - 1); 872 if (result % 10 >= 5) 873 result += 10; 874 result /= 10; 875 return Decimal(sign(), 0, result); 876 } 877 878 double Decimal::toDouble() const 879 { 880 if (isFinite()) { 881 bool valid; 882 const double doubleValue = mozToDouble(toString(), &valid); 883 return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN(); 884 } 885 886 if (isInfinity()) 887 return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity(); 888 889 return std::numeric_limits<double>::quiet_NaN(); 890 } 891 892 String Decimal::toString() const 893 { 894 switch (m_data.formatClass()) { 895 case EncodedData::ClassInfinity: 896 return sign() ? "-Infinity" : "Infinity"; 897 898 case EncodedData::ClassNaN: 899 return "NaN"; 900 901 case EncodedData::ClassNormal: 902 case EncodedData::ClassZero: 903 break; 904 905 default: 906 ASSERT_NOT_REACHED(); 907 return ""; 908 } 909 910 StringBuilder builder; 911 if (sign()) 912 builder.append('-'); 913 914 int originalExponent = exponent(); 915 uint64_t coefficient = m_data.coefficient(); 916 917 if (originalExponent < 0) { 918 const int maxDigits = DBL_DIG; 919 uint64_t lastDigit = 0; 920 while (countDigits(coefficient) > maxDigits) { 921 lastDigit = coefficient % 10; 922 coefficient /= 10; 923 ++originalExponent; 924 } 925 926 if (lastDigit >= 5) 927 ++coefficient; 928 929 while (originalExponent < 0 && coefficient && !(coefficient % 10)) { 930 coefficient /= 10; 931 ++originalExponent; 932 } 933 } 934 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(); 942 } 943 944 if (adjustedExponent >= 0) { 945 for (int i = 0; i < coefficientLength; ++i) { 946 builder.append(digits[i]); 947 if (i == adjustedExponent) 948 builder.append('.'); 949 } 950 return builder.toString(); 951 } 952 953 builder.appendLiteral("0."); 954 for (int i = adjustedExponent + 1; i < 0; ++i) 955 builder.append('0'); 956 957 builder.append(digits); 958 959 } else { 960 builder.append(digits[0]); 961 while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0') 962 --coefficientLength; 963 if (coefficientLength >= 2) { 964 builder.append('.'); 965 for (int i = 1; i < coefficientLength; ++i) 966 builder.append(digits[i]); 967 } 968 969 if (adjustedExponent) { 970 builder.append(adjustedExponent < 0 ? "e" : "e+"); 971 builder.appendNumber(adjustedExponent); 972 } 973 } 974 return builder.toString(); 975 } 976 977 Decimal Decimal::zero(Sign sign) 978 { 979 return Decimal(EncodedData(sign, EncodedData::ClassZero)); 980 } 981 982 } // namespace blink 983 984 // Implementation of DoubleConversion.h: 985 986 namespace mozilla { 987 988 Maybe<double> StringToDouble(Span<const char> aStringSpan) { 989 bool valid = false; 990 double result = mozToDouble(aStringSpan, &valid); 991 return valid ? Some(result) : Nothing(); 992 } 993 994 }