1/* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2013 Apple Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "config.h" 33#include "Decimal.h" 34 35#include <algorithm> 36#include <float.h> 37 38#include <wtf/Assertions.h> 39#include <wtf/MathExtras.h> 40#include <wtf/Noncopyable.h> 41#include <wtf/text/StringBuilder.h> 42 43namespace WebCore { 44 45namespace DecimalPrivate { 46 47static int const ExponentMax = 1023; 48static int const ExponentMin = -1023; 49static int const Precision = 18; 50 51static const uint64_t MaxCoefficient = UINT64_C(0x16345785D89FFFF); // 999999999999999999 == 18 9's 52 53// This class handles Decimal special values. 54class SpecialValueHandler { 55 WTF_MAKE_NONCOPYABLE(SpecialValueHandler); 56public: 57 enum HandleResult { 58 BothFinite, 59 BothInfinity, 60 EitherNaN, 61 LHSIsInfinity, 62 RHSIsInfinity, 63 }; 64 65 SpecialValueHandler(const Decimal& lhs, const Decimal& rhs); 66 HandleResult handle(); 67 Decimal value() const; 68 69private: 70 enum Result { 71 ResultIsLHS, 72 ResultIsRHS, 73 ResultIsUnknown, 74 }; 75 76 const Decimal& m_lhs; 77 const Decimal& m_rhs; 78 Result m_result; 79}; 80 81SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs) 82 : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown) 83{ 84} 85 86SpecialValueHandler::HandleResult SpecialValueHandler::handle() 87{ 88 if (m_lhs.isFinite() && m_rhs.isFinite()) 89 return BothFinite; 90 91 const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass(); 92 const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass(); 93 if (lhsClass == Decimal::EncodedData::ClassNaN) { 94 m_result = ResultIsLHS; 95 return EitherNaN; 96 } 97 98 if (rhsClass == Decimal::EncodedData::ClassNaN) { 99 m_result = ResultIsRHS; 100 return EitherNaN; 101 } 102 103 if (lhsClass == Decimal::EncodedData::ClassInfinity) 104 return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity; 105 106 if (rhsClass == Decimal::EncodedData::ClassInfinity) 107 return RHSIsInfinity; 108 109 ASSERT_NOT_REACHED(); 110 return BothFinite; 111} 112 113Decimal SpecialValueHandler::value() const 114{ 115 switch (m_result) { 116 case ResultIsLHS: 117 return m_lhs; 118 case ResultIsRHS: 119 return m_rhs; 120 case ResultIsUnknown: 121 default: 122 ASSERT_NOT_REACHED(); 123 return m_lhs; 124 } 125} 126 127// This class is used for 128 bit unsigned integer arithmetic. 128class UInt128 { 129public: 130 UInt128(uint64_t low, uint64_t high) 131 : m_high(high), m_low(low) 132 { 133 } 134 135 UInt128& operator/=(uint32_t); 136 137 uint64_t high() const { return m_high; } 138 uint64_t low() const { return m_low; } 139 140 static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); } 141 142private: 143 static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); } 144 static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); } 145 bool isZero() const { return !m_low && !m_high; } 146 static uint64_t makeUInt64(uint32_t low, uint32_t high) { return low | (static_cast<uint64_t>(high) << 32); } 147 148 static uint64_t multiplyHigh(uint64_t, uint64_t); 149 150 uint64_t m_high; 151 uint64_t m_low; 152}; 153 154UInt128& UInt128::operator/=(const uint32_t divisor) 155{ 156 ASSERT(divisor); 157 158 if (!m_high) { 159 m_low /= divisor; 160 return *this; 161 } 162 163 uint32_t dividend[4]; 164 dividend[0] = lowUInt32(m_low); 165 dividend[1] = highUInt32(m_low); 166 dividend[2] = lowUInt32(m_high); 167 dividend[3] = highUInt32(m_high); 168 169 uint32_t quotient[4]; 170 uint32_t remainder = 0; 171 for (int i = 3; i >= 0; --i) { 172 const uint64_t work = makeUInt64(dividend[i], remainder); 173 remainder = static_cast<uint32_t>(work % divisor); 174 quotient[i] = static_cast<uint32_t>(work / divisor); 175 } 176 m_low = makeUInt64(quotient[0], quotient[1]); 177 m_high = makeUInt64(quotient[2], quotient[3]); 178 return *this; 179} 180 181// Returns high 64bit of 128bit product. 182uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v) 183{ 184 const uint64_t uLow = lowUInt32(u); 185 const uint64_t uHigh = highUInt32(u); 186 const uint64_t vLow = lowUInt32(v); 187 const uint64_t vHigh = highUInt32(v); 188 const uint64_t partialProduct = uHigh * vLow + highUInt32(uLow * vLow); 189 return uHigh * vHigh + highUInt32(partialProduct) + highUInt32(uLow * vHigh + lowUInt32(partialProduct)); 190} 191 192static int countDigits(uint64_t x) 193{ 194 int numberOfDigits = 0; 195 for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) { 196 ++numberOfDigits; 197 if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10) 198 break; 199 } 200 return numberOfDigits; 201} 202 203static uint64_t scaleDown(uint64_t x, int n) 204{ 205 ASSERT(n >= 0); 206 while (n > 0 && x) { 207 x /= 10; 208 --n; 209 } 210 return x; 211} 212 213static uint64_t scaleUp(uint64_t x, int n) 214{ 215 ASSERT(n >= 0); 216 ASSERT(n < Precision); 217 218 uint64_t y = 1; 219 uint64_t z = 10; 220 for (;;) { 221 if (n & 1) 222 y = y * z; 223 224 n >>= 1; 225 if (!n) 226 return x * y; 227 228 z = z * z; 229 } 230} 231 232} // namespace DecimalPrivate 233 234using namespace DecimalPrivate; 235 236Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass) 237 : m_coefficient(0) 238 , m_exponent(0) 239 , m_formatClass(formatClass) 240 , m_sign(sign) 241{ 242} 243 244Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient) 245 : m_formatClass(coefficient ? ClassNormal : ClassZero) 246 , m_sign(sign) 247{ 248 if (exponent >= ExponentMin && exponent <= ExponentMax) { 249 while (coefficient > MaxCoefficient) { 250 coefficient /= 10; 251 ++exponent; 252 } 253 } 254 255 if (exponent > ExponentMax) { 256 m_coefficient = 0; 257 m_exponent = 0; 258 m_formatClass = ClassInfinity; 259 return; 260 } 261 262 if (exponent < ExponentMin) { 263 m_coefficient = 0; 264 m_exponent = 0; 265 m_formatClass = ClassZero; 266 return; 267 } 268 269 m_coefficient = coefficient; 270 m_exponent = static_cast<int16_t>(exponent); 271} 272 273bool Decimal::EncodedData::operator==(const EncodedData& another) const 274{ 275 return m_sign == another.m_sign 276 && m_formatClass == another.m_formatClass 277 && m_exponent == another.m_exponent 278 && m_coefficient == another.m_coefficient; 279} 280 281Decimal::Decimal(int32_t i32) 282 : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32)) 283{ 284} 285 286Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient) 287 : m_data(sign, exponent, coefficient) 288{ 289} 290 291Decimal::Decimal(const EncodedData& data) 292 : m_data(data) 293{ 294} 295 296Decimal::Decimal(const Decimal& other) 297 : m_data(other.m_data) 298{ 299} 300 301Decimal& Decimal::operator=(const Decimal& other) 302{ 303 m_data = other.m_data; 304 return *this; 305} 306 307Decimal& Decimal::operator+=(const Decimal& other) 308{ 309 m_data = (*this + other).m_data; 310 return *this; 311} 312 313Decimal& Decimal::operator-=(const Decimal& other) 314{ 315 m_data = (*this - other).m_data; 316 return *this; 317} 318 319Decimal& Decimal::operator*=(const Decimal& other) 320{ 321 m_data = (*this * other).m_data; 322 return *this; 323} 324 325Decimal& Decimal::operator/=(const Decimal& other) 326{ 327 m_data = (*this / other).m_data; 328 return *this; 329} 330 331Decimal Decimal::operator-() const 332{ 333 if (isNaN()) 334 return *this; 335 336 Decimal result(*this); 337 result.m_data.setSign(invertSign(m_data.sign())); 338 return result; 339} 340 341Decimal Decimal::operator+(const Decimal& rhs) const 342{ 343 const Decimal& lhs = *this; 344 const Sign lhsSign = lhs.sign(); 345 const Sign rhsSign = rhs.sign(); 346 347 SpecialValueHandler handler(lhs, rhs); 348 switch (handler.handle()) { 349 case SpecialValueHandler::BothFinite: 350 break; 351 352 case SpecialValueHandler::BothInfinity: 353 return lhsSign == rhsSign ? lhs : nan(); 354 355 case SpecialValueHandler::EitherNaN: 356 return handler.value(); 357 358 case SpecialValueHandler::LHSIsInfinity: 359 return lhs; 360 361 case SpecialValueHandler::RHSIsInfinity: 362 return rhs; 363 } 364 365 const AlignedOperands alignedOperands = alignOperands(lhs, rhs); 366 367 const uint64_t result = lhsSign == rhsSign 368 ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient 369 : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient; 370 371 if (lhsSign == Negative && rhsSign == Positive && !result) 372 return Decimal(Positive, alignedOperands.exponent, 0); 373 374 return static_cast<int64_t>(result) >= 0 375 ? Decimal(lhsSign, alignedOperands.exponent, result) 376 : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result)); 377} 378 379Decimal Decimal::operator-(const Decimal& rhs) const 380{ 381 const Decimal& lhs = *this; 382 const Sign lhsSign = lhs.sign(); 383 const Sign rhsSign = rhs.sign(); 384 385 SpecialValueHandler handler(lhs, rhs); 386 switch (handler.handle()) { 387 case SpecialValueHandler::BothFinite: 388 break; 389 390 case SpecialValueHandler::BothInfinity: 391 return lhsSign == rhsSign ? nan() : lhs; 392 393 case SpecialValueHandler::EitherNaN: 394 return handler.value(); 395 396 case SpecialValueHandler::LHSIsInfinity: 397 return lhs; 398 399 case SpecialValueHandler::RHSIsInfinity: 400 return infinity(invertSign(rhsSign)); 401 } 402 403 const AlignedOperands alignedOperands = alignOperands(lhs, rhs); 404 405 const uint64_t result = lhsSign == rhsSign 406 ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient 407 : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient; 408 409 if (lhsSign == Negative && rhsSign == Negative && !result) 410 return Decimal(Positive, alignedOperands.exponent, 0); 411 412 return static_cast<int64_t>(result) >= 0 413 ? Decimal(lhsSign, alignedOperands.exponent, result) 414 : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result)); 415} 416 417Decimal Decimal::operator*(const Decimal& rhs) const 418{ 419 const Decimal& lhs = *this; 420 const Sign lhsSign = lhs.sign(); 421 const Sign rhsSign = rhs.sign(); 422 const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; 423 424 SpecialValueHandler handler(lhs, rhs); 425 switch (handler.handle()) { 426 case SpecialValueHandler::BothFinite: { 427 const uint64_t lhsCoefficient = lhs.m_data.coefficient(); 428 const uint64_t rhsCoefficient = rhs.m_data.coefficient(); 429 int resultExponent = lhs.exponent() + rhs.exponent(); 430 UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient)); 431 while (work.high()) { 432 work /= 10; 433 ++resultExponent; 434 } 435 return Decimal(resultSign, resultExponent, work.low()); 436 } 437 438 case SpecialValueHandler::BothInfinity: 439 return infinity(resultSign); 440 441 case SpecialValueHandler::EitherNaN: 442 return handler.value(); 443 444 case SpecialValueHandler::LHSIsInfinity: 445 return rhs.isZero() ? nan() : infinity(resultSign); 446 447 case SpecialValueHandler::RHSIsInfinity: 448 return lhs.isZero() ? nan() : infinity(resultSign); 449 } 450 451 ASSERT_NOT_REACHED(); 452 return nan(); 453} 454 455Decimal Decimal::operator/(const Decimal& rhs) const 456{ 457 const Decimal& lhs = *this; 458 const Sign lhsSign = lhs.sign(); 459 const Sign rhsSign = rhs.sign(); 460 const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; 461 462 SpecialValueHandler handler(lhs, rhs); 463 switch (handler.handle()) { 464 case SpecialValueHandler::BothFinite: 465 break; 466 467 case SpecialValueHandler::BothInfinity: 468 return nan(); 469 470 case SpecialValueHandler::EitherNaN: 471 return handler.value(); 472 473 case SpecialValueHandler::LHSIsInfinity: 474 return infinity(resultSign); 475 476 case SpecialValueHandler::RHSIsInfinity: 477 return zero(resultSign); 478 } 479 480 ASSERT(lhs.isFinite()); 481 ASSERT(rhs.isFinite()); 482 483 if (rhs.isZero()) 484 return lhs.isZero() ? nan() : infinity(resultSign); 485 486 int resultExponent = lhs.exponent() - rhs.exponent(); 487 488 if (lhs.isZero()) 489 return Decimal(resultSign, resultExponent, 0); 490 491 uint64_t remainder = lhs.m_data.coefficient(); 492 const uint64_t divisor = rhs.m_data.coefficient(); 493 uint64_t result = 0; 494 while (result < MaxCoefficient / 100) { 495 while (remainder < divisor) { 496 remainder *= 10; 497 result *= 10; 498 --resultExponent; 499 } 500 result += remainder / divisor; 501 remainder %= divisor; 502 if (!remainder) 503 break; 504 } 505 506 if (remainder > divisor / 2) 507 ++result; 508 509 return Decimal(resultSign, resultExponent, result); 510} 511 512bool Decimal::operator==(const Decimal& rhs) const 513{ 514 return m_data == rhs.m_data || compareTo(rhs).isZero(); 515} 516 517bool Decimal::operator!=(const Decimal& rhs) const 518{ 519 if (m_data == rhs.m_data) 520 return false; 521 const Decimal result = compareTo(rhs); 522 if (result.isNaN()) 523 return false; 524 return !result.isZero(); 525} 526 527bool Decimal::operator<(const Decimal& rhs) const 528{ 529 const Decimal result = compareTo(rhs); 530 if (result.isNaN()) 531 return false; 532 return !result.isZero() && result.isNegative(); 533} 534 535bool Decimal::operator<=(const Decimal& rhs) const 536{ 537 if (m_data == rhs.m_data) 538 return true; 539 const Decimal result = compareTo(rhs); 540 if (result.isNaN()) 541 return false; 542 return result.isZero() || result.isNegative(); 543} 544 545bool Decimal::operator>(const Decimal& rhs) const 546{ 547 const Decimal result = compareTo(rhs); 548 if (result.isNaN()) 549 return false; 550 return !result.isZero() && result.isPositive(); 551} 552 553bool Decimal::operator>=(const Decimal& rhs) const 554{ 555 if (m_data == rhs.m_data) 556 return true; 557 const Decimal result = compareTo(rhs); 558 if (result.isNaN()) 559 return false; 560 return result.isZero() || !result.isNegative(); 561} 562 563Decimal Decimal::abs() const 564{ 565 Decimal result(*this); 566 result.m_data.setSign(Positive); 567 return result; 568} 569 570Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs) 571{ 572 ASSERT(lhs.isFinite()); 573 ASSERT(rhs.isFinite()); 574 575 const int lhsExponent = lhs.exponent(); 576 const int rhsExponent = rhs.exponent(); 577 int exponent = std::min(lhsExponent, rhsExponent); 578 uint64_t lhsCoefficient = lhs.m_data.coefficient(); 579 uint64_t rhsCoefficient = rhs.m_data.coefficient(); 580 581 if (lhsExponent > rhsExponent) { 582 const int numberOfLHSDigits = countDigits(lhsCoefficient); 583 if (numberOfLHSDigits) { 584 const int lhsShiftAmount = lhsExponent - rhsExponent; 585 const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision; 586 if (overflow <= 0) 587 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount); 588 else { 589 lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow); 590 rhsCoefficient = scaleDown(rhsCoefficient, overflow); 591 exponent += overflow; 592 } 593 } 594 595 } else if (lhsExponent < rhsExponent) { 596 const int numberOfRHSDigits = countDigits(rhsCoefficient); 597 if (numberOfRHSDigits) { 598 const int rhsShiftAmount = rhsExponent - lhsExponent; 599 const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision; 600 if (overflow <= 0) 601 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount); 602 else { 603 rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow); 604 lhsCoefficient = scaleDown(lhsCoefficient, overflow); 605 exponent += overflow; 606 } 607 } 608 } 609 610 AlignedOperands alignedOperands; 611 alignedOperands.exponent = exponent; 612 alignedOperands.lhsCoefficient = lhsCoefficient; 613 alignedOperands.rhsCoefficient = rhsCoefficient; 614 return alignedOperands; 615} 616 617// Round toward positive infinity. 618// Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" here. 619Decimal Decimal::ceiling() const 620{ 621 if (isSpecial()) 622 return *this; 623 624 if (exponent() >= 0) 625 return *this; 626 627 uint64_t result = m_data.coefficient(); 628 const int numberOfDigits = countDigits(result); 629 const int numberOfDropDigits = -exponent(); 630 if (numberOfDigits < numberOfDropDigits) 631 return isPositive() ? Decimal(1) : zero(Positive); 632 633 result = scaleDown(result, numberOfDropDigits - 1); 634 if (sign() == Positive && result % 10 > 0) 635 result += 10; 636 result /= 10; 637 return Decimal(sign(), 0, result); 638} 639 640Decimal Decimal::compareTo(const Decimal& rhs) const 641{ 642 const Decimal result(*this - rhs); 643 switch (result.m_data.formatClass()) { 644 case EncodedData::ClassInfinity: 645 return result.isNegative() ? Decimal(-1) : Decimal(1); 646 647 case EncodedData::ClassNaN: 648 case EncodedData::ClassNormal: 649 return result; 650 651 case EncodedData::ClassZero: 652 return zero(Positive); 653 654 default: 655 ASSERT_NOT_REACHED(); 656 return nan(); 657 } 658} 659 660// Round toward negative infinity. 661Decimal Decimal::floor() const 662{ 663 if (isSpecial()) 664 return *this; 665 666 if (exponent() >= 0) 667 return *this; 668 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); 674 675 result = scaleDown(result, numberOfDropDigits - 1); 676 if (isNegative() && result % 10 > 0) 677 result += 10; 678 result /= 10; 679 return Decimal(sign(), 0, result); 680} 681 682Decimal Decimal::fromDouble(double doubleValue) 683{ 684 if (std::isfinite(doubleValue)) 685 return fromString(String::numberToStringECMAScript(doubleValue)); 686 687 if (std::isinf(doubleValue)) 688 return infinity(doubleValue < 0 ? Negative : Positive); 689 690 return nan(); 691} 692 693Decimal Decimal::fromString(const String& str) 694{ 695 int exponent = 0; 696 Sign exponentSign = Positive; 697 int numberOfDigits = 0; 698 int numberOfDigitsAfterDot = 0; 699 int numberOfExtraDigits = 0; 700 Sign sign = Positive; 701 702 enum { 703 StateDigit, 704 StateDot, 705 StateDotDigit, 706 StateE, 707 StateEDigit, 708 StateESign, 709 StateSign, 710 StateStart, 711 StateZero, 712 } state = StateStart; 713 714#define HandleCharAndBreak(expected, nextState) \ 715 if (ch == expected) { \ 716 state = nextState; \ 717 break; \ 718 } 719 720#define HandleTwoCharsAndBreak(expected1, expected2, nextState) \ 721 if (ch == expected1 || ch == expected2) { \ 722 state = nextState; \ 723 break; \ 724 } 725 726 uint64_t accumulator = 0; 727 for (unsigned index = 0; index < str.length(); ++index) { 728 const int ch = str[index]; 729 switch (state) { 730 case StateDigit: 731 if (ch >= '0' && ch <= '9') { 732 if (numberOfDigits < Precision) { 733 ++numberOfDigits; 734 accumulator *= 10; 735 accumulator += ch - '0'; 736 } else 737 ++numberOfExtraDigits; 738 break; 739 } 740 741 HandleCharAndBreak('.', StateDot); 742 HandleTwoCharsAndBreak('E', 'e', StateE); 743 return nan(); 744 745 case StateDot: 746 if (ch >= '0' && ch <= '9') { 747 if (numberOfDigits < Precision) { 748 ++numberOfDigits; 749 ++numberOfDigitsAfterDot; 750 accumulator *= 10; 751 accumulator += ch - '0'; 752 } 753 state = StateDotDigit; 754 break; 755 } 756 757 case StateDotDigit: 758 if (ch >= '0' && ch <= '9') { 759 if (numberOfDigits < Precision) { 760 ++numberOfDigits; 761 ++numberOfDigitsAfterDot; 762 accumulator *= 10; 763 accumulator += ch - '0'; 764 } 765 break; 766 } 767 768 HandleTwoCharsAndBreak('E', 'e', StateE); 769 return nan(); 770 771 case StateE: 772 if (ch == '+') { 773 exponentSign = Positive; 774 state = StateESign; 775 break; 776 } 777 778 if (ch == '-') { 779 exponentSign = Negative; 780 state = StateESign; 781 break; 782 } 783 784 if (ch >= '0' && ch <= '9') { 785 exponent = ch - '0'; 786 state = StateEDigit; 787 break; 788 } 789 790 return nan(); 791 792 case StateEDigit: 793 if (ch >= '0' && ch <= '9') { 794 exponent *= 10; 795 exponent += ch - '0'; 796 if (exponent > ExponentMax + Precision) { 797 if (accumulator) 798 return exponentSign == Negative ? zero(Positive) : infinity(sign); 799 return zero(sign); 800 } 801 state = StateEDigit; 802 break; 803 } 804 805 return nan(); 806 807 case StateESign: 808 if (ch >= '0' && ch <= '9') { 809 exponent = ch - '0'; 810 state = StateEDigit; 811 break; 812 } 813 814 return nan(); 815 816 case StateSign: 817 if (ch >= '1' && ch <= '9') { 818 accumulator = ch - '0'; 819 numberOfDigits = 1; 820 state = StateDigit; 821 break; 822 } 823 824 HandleCharAndBreak('0', StateZero); 825 return nan(); 826 827 case StateStart: 828 if (ch >= '1' && ch <= '9') { 829 accumulator = ch - '0'; 830 numberOfDigits = 1; 831 state = StateDigit; 832 break; 833 } 834 835 if (ch == '-') { 836 sign = Negative; 837 state = StateSign; 838 break; 839 } 840 841 if (ch == '+') { 842 sign = Positive; 843 state = StateSign; 844 break; 845 } 846 847 HandleCharAndBreak('0', StateZero); 848 HandleCharAndBreak('.', StateDot); 849 return nan(); 850 851 case StateZero: 852 if (ch == '0') 853 break; 854 855 if (ch >= '1' && ch <= '9') { 856 accumulator = ch - '0'; 857 numberOfDigits = 1; 858 state = StateDigit; 859 break; 860 } 861 862 HandleCharAndBreak('.', StateDot); 863 HandleTwoCharsAndBreak('E', 'e', StateE); 864 return nan(); 865 866 default: 867 ASSERT_NOT_REACHED(); 868 return nan(); 869 } 870 } 871 872 if (state == StateZero) 873 return zero(sign); 874 875 if (state == StateDigit || state == StateEDigit || state == StateDotDigit) { 876 int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits; 877 if (resultExponent < ExponentMin) 878 return zero(Positive); 879 880 const int overflow = resultExponent - ExponentMax + 1; 881 if (overflow > 0) { 882 if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision) 883 return infinity(sign); 884 accumulator = scaleUp(accumulator, overflow); 885 resultExponent -= overflow; 886 } 887 888 return Decimal(sign, resultExponent, accumulator); 889 } 890 891 return nan(); 892} 893 894Decimal Decimal::infinity(const Sign sign) 895{ 896 return Decimal(EncodedData(sign, EncodedData::ClassInfinity)); 897} 898 899Decimal Decimal::nan() 900{ 901 return Decimal(EncodedData(Positive, EncodedData::ClassNaN)); 902} 903 904Decimal Decimal::remainder(const Decimal& rhs) const 905{ 906 const Decimal quotient = *this / rhs; 907 return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceiling() : quotient.floor()) * rhs; 908} 909 910Decimal Decimal::round() const 911{ 912 if (isSpecial()) 913 return *this; 914 915 if (exponent() >= 0) 916 return *this; 917 918 uint64_t result = m_data.coefficient(); 919 const int numberOfDigits = countDigits(result); 920 const int numberOfDropDigits = -exponent(); 921 if (numberOfDigits < numberOfDropDigits) 922 return zero(Positive); 923 924 result = scaleDown(result, numberOfDropDigits - 1); 925 if (result % 10 >= 5) 926 result += 10; 927 result /= 10; 928 return Decimal(sign(), 0, result); 929} 930 931double Decimal::toDouble() const 932{ 933 if (isFinite()) { 934 bool valid; 935 const double doubleValue = toString().toDouble(&valid); 936 return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN(); 937 } 938 939 if (isInfinity()) 940 return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity(); 941 942 return std::numeric_limits<double>::quiet_NaN(); 943} 944 945String Decimal::toString() const 946{ 947 switch (m_data.formatClass()) { 948 case EncodedData::ClassInfinity: 949 return sign() ? ASCIILiteral("-Infinity") : ASCIILiteral("Infinity"); 950 951 case EncodedData::ClassNaN: 952 return ASCIILiteral("NaN"); 953 954 case EncodedData::ClassNormal: 955 case EncodedData::ClassZero: 956 break; 957 958 default: 959 ASSERT_NOT_REACHED(); 960 return emptyString(); 961 } 962 963 StringBuilder builder; 964 if (sign()) 965 builder.append('-'); 966 967 int originalExponent = exponent(); 968 uint64_t coefficient = m_data.coefficient(); 969 970 if (originalExponent < 0) { 971 const int maxDigits = DBL_DIG; 972 uint64_t lastDigit = 0; 973 while (countDigits(coefficient) > maxDigits) { 974 lastDigit = coefficient % 10; 975 coefficient /= 10; 976 ++originalExponent; 977 } 978 979 if (lastDigit >= 5) 980 ++coefficient; 981 982 while (originalExponent < 0 && coefficient && !(coefficient % 10)) { 983 coefficient /= 10; 984 ++originalExponent; 985 } 986 } 987 988 const String digits = String::number(coefficient); 989 int coefficientLength = static_cast<int>(digits.length()); 990 const int adjustedExponent = originalExponent + coefficientLength - 1; 991 if (originalExponent <= 0 && adjustedExponent >= -6) { 992 if (!originalExponent) { 993 builder.append(digits); 994 return builder.toString(); 995 } 996 997 if (adjustedExponent >= 0) { 998 for (int i = 0; i < coefficientLength; ++i) { 999 builder.append(digits[i]); 1000 if (i == adjustedExponent) 1001 builder.append('.'); 1002 } 1003 return builder.toString(); 1004 } 1005 1006 builder.appendLiteral("0."); 1007 for (int i = adjustedExponent + 1; i < 0; ++i) 1008 builder.append('0'); 1009 1010 builder.append(digits); 1011 1012 } else { 1013 builder.append(digits[0]); 1014 while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0') 1015 --coefficientLength; 1016 if (coefficientLength >= 2) { 1017 builder.append('.'); 1018 for (int i = 1; i < coefficientLength; ++i) 1019 builder.append(digits[i]); 1020 } 1021 1022 if (adjustedExponent) { 1023 builder.append(adjustedExponent < 0 ? "e" : "e+"); 1024 builder.appendNumber(adjustedExponent); 1025 } 1026 } 1027 return builder.toString(); 1028} 1029 1030Decimal Decimal::zero(Sign sign) 1031{ 1032 return Decimal(EncodedData(sign, EncodedData::ClassZero)); 1033} 1034 1035} // namespace WebCore 1036