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