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