| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs) | 80 SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs) |
| 81 : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown) | 81 : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown) |
| 82 { | 82 { |
| 83 } | 83 } |
| 84 | 84 |
| 85 SpecialValueHandler::HandleResult SpecialValueHandler::handle() | 85 SpecialValueHandler::HandleResult SpecialValueHandler::handle() |
| 86 { | 86 { |
| 87 if (m_lhs.isFinite() && m_rhs.isFinite()) | 87 if (m_lhs.isFinite() && m_rhs.isFinite()) |
| 88 return BothFinite; | 88 return BothFinite; |
| 89 | 89 |
| 90 const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass
(); | 90 const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().getFormatCl
ass(); |
| 91 const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass
(); | 91 const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().getFormatCl
ass(); |
| 92 if (lhsClass == Decimal::EncodedData::ClassNaN) { | 92 if (lhsClass == Decimal::EncodedData::ClassNaN) { |
| 93 m_result = ResultIsLHS; | 93 m_result = ResultIsLHS; |
| 94 return EitherNaN; | 94 return EitherNaN; |
| 95 } | 95 } |
| 96 | 96 |
| 97 if (rhsClass == Decimal::EncodedData::ClassNaN) { | 97 if (rhsClass == Decimal::EncodedData::ClassNaN) { |
| 98 m_result = ResultIsRHS; | 98 m_result = ResultIsRHS; |
| 99 return EitherNaN; | 99 return EitherNaN; |
| 100 } | 100 } |
| 101 | 101 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 m_data = (*this / other).m_data; | 325 m_data = (*this / other).m_data; |
| 326 return *this; | 326 return *this; |
| 327 } | 327 } |
| 328 | 328 |
| 329 Decimal Decimal::operator-() const | 329 Decimal Decimal::operator-() const |
| 330 { | 330 { |
| 331 if (isNaN()) | 331 if (isNaN()) |
| 332 return *this; | 332 return *this; |
| 333 | 333 |
| 334 Decimal result(*this); | 334 Decimal result(*this); |
| 335 result.m_data.setSign(invertSign(m_data.sign())); | 335 result.m_data.setSign(invertSign(m_data.getSign())); |
| 336 return result; | 336 return result; |
| 337 } | 337 } |
| 338 | 338 |
| 339 Decimal Decimal::operator+(const Decimal& rhs) const | 339 Decimal Decimal::operator+(const Decimal& rhs) const |
| 340 { | 340 { |
| 341 const Decimal& lhs = *this; | 341 const Decimal& lhs = *this; |
| 342 const Sign lhsSign = lhs.sign(); | 342 const Sign lhsSign = lhs.getSign(); |
| 343 const Sign rhsSign = rhs.sign(); | 343 const Sign rhsSign = rhs.getSign(); |
| 344 | 344 |
| 345 SpecialValueHandler handler(lhs, rhs); | 345 SpecialValueHandler handler(lhs, rhs); |
| 346 switch (handler.handle()) { | 346 switch (handler.handle()) { |
| 347 case SpecialValueHandler::BothFinite: | 347 case SpecialValueHandler::BothFinite: |
| 348 break; | 348 break; |
| 349 | 349 |
| 350 case SpecialValueHandler::BothInfinity: | 350 case SpecialValueHandler::BothInfinity: |
| 351 return lhsSign == rhsSign ? lhs : nan(); | 351 return lhsSign == rhsSign ? lhs : nan(); |
| 352 | 352 |
| 353 case SpecialValueHandler::EitherNaN: | 353 case SpecialValueHandler::EitherNaN: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 370 return Decimal(Positive, alignedOperands.exponent, 0); | 370 return Decimal(Positive, alignedOperands.exponent, 0); |
| 371 | 371 |
| 372 return static_cast<int64_t>(result) >= 0 | 372 return static_cast<int64_t>(result) >= 0 |
| 373 ? Decimal(lhsSign, alignedOperands.exponent, result) | 373 ? Decimal(lhsSign, alignedOperands.exponent, result) |
| 374 : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<in
t64_t>(result)); | 374 : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<in
t64_t>(result)); |
| 375 } | 375 } |
| 376 | 376 |
| 377 Decimal Decimal::operator-(const Decimal& rhs) const | 377 Decimal Decimal::operator-(const Decimal& rhs) const |
| 378 { | 378 { |
| 379 const Decimal& lhs = *this; | 379 const Decimal& lhs = *this; |
| 380 const Sign lhsSign = lhs.sign(); | 380 const Sign lhsSign = lhs.getSign(); |
| 381 const Sign rhsSign = rhs.sign(); | 381 const Sign rhsSign = rhs.getSign(); |
| 382 | 382 |
| 383 SpecialValueHandler handler(lhs, rhs); | 383 SpecialValueHandler handler(lhs, rhs); |
| 384 switch (handler.handle()) { | 384 switch (handler.handle()) { |
| 385 case SpecialValueHandler::BothFinite: | 385 case SpecialValueHandler::BothFinite: |
| 386 break; | 386 break; |
| 387 | 387 |
| 388 case SpecialValueHandler::BothInfinity: | 388 case SpecialValueHandler::BothInfinity: |
| 389 return lhsSign == rhsSign ? nan() : lhs; | 389 return lhsSign == rhsSign ? nan() : lhs; |
| 390 | 390 |
| 391 case SpecialValueHandler::EitherNaN: | 391 case SpecialValueHandler::EitherNaN: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 408 return Decimal(Positive, alignedOperands.exponent, 0); | 408 return Decimal(Positive, alignedOperands.exponent, 0); |
| 409 | 409 |
| 410 return static_cast<int64_t>(result) >= 0 | 410 return static_cast<int64_t>(result) >= 0 |
| 411 ? Decimal(lhsSign, alignedOperands.exponent, result) | 411 ? Decimal(lhsSign, alignedOperands.exponent, result) |
| 412 : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<in
t64_t>(result)); | 412 : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<in
t64_t>(result)); |
| 413 } | 413 } |
| 414 | 414 |
| 415 Decimal Decimal::operator*(const Decimal& rhs) const | 415 Decimal Decimal::operator*(const Decimal& rhs) const |
| 416 { | 416 { |
| 417 const Decimal& lhs = *this; | 417 const Decimal& lhs = *this; |
| 418 const Sign lhsSign = lhs.sign(); | 418 const Sign lhsSign = lhs.getSign(); |
| 419 const Sign rhsSign = rhs.sign(); | 419 const Sign rhsSign = rhs.getSign(); |
| 420 const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; | 420 const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; |
| 421 | 421 |
| 422 SpecialValueHandler handler(lhs, rhs); | 422 SpecialValueHandler handler(lhs, rhs); |
| 423 switch (handler.handle()) { | 423 switch (handler.handle()) { |
| 424 case SpecialValueHandler::BothFinite: { | 424 case SpecialValueHandler::BothFinite: { |
| 425 const uint64_t lhsCoefficient = lhs.m_data.coefficient(); | 425 const uint64_t lhsCoefficient = lhs.m_data.coefficient(); |
| 426 const uint64_t rhsCoefficient = rhs.m_data.coefficient(); | 426 const uint64_t rhsCoefficient = rhs.m_data.coefficient(); |
| 427 int resultExponent = lhs.exponent() + rhs.exponent(); | 427 int resultExponent = lhs.exponent() + rhs.exponent(); |
| 428 UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient)); | 428 UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient)); |
| 429 while (work.high()) { | 429 while (work.high()) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 446 return lhs.isZero() ? nan() : infinity(resultSign); | 446 return lhs.isZero() ? nan() : infinity(resultSign); |
| 447 } | 447 } |
| 448 | 448 |
| 449 ASSERT_NOT_REACHED(); | 449 ASSERT_NOT_REACHED(); |
| 450 return nan(); | 450 return nan(); |
| 451 } | 451 } |
| 452 | 452 |
| 453 Decimal Decimal::operator/(const Decimal& rhs) const | 453 Decimal Decimal::operator/(const Decimal& rhs) const |
| 454 { | 454 { |
| 455 const Decimal& lhs = *this; | 455 const Decimal& lhs = *this; |
| 456 const Sign lhsSign = lhs.sign(); | 456 const Sign lhsSign = lhs.getSign(); |
| 457 const Sign rhsSign = rhs.sign(); | 457 const Sign rhsSign = rhs.getSign(); |
| 458 const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; | 458 const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; |
| 459 | 459 |
| 460 SpecialValueHandler handler(lhs, rhs); | 460 SpecialValueHandler handler(lhs, rhs); |
| 461 switch (handler.handle()) { | 461 switch (handler.handle()) { |
| 462 case SpecialValueHandler::BothFinite: | 462 case SpecialValueHandler::BothFinite: |
| 463 break; | 463 break; |
| 464 | 464 |
| 465 case SpecialValueHandler::BothInfinity: | 465 case SpecialValueHandler::BothInfinity: |
| 466 return nan(); | 466 return nan(); |
| 467 | 467 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 | 633 |
| 634 uint64_t result = m_data.coefficient(); | 634 uint64_t result = m_data.coefficient(); |
| 635 const int numberOfDigits = countDigits(result); | 635 const int numberOfDigits = countDigits(result); |
| 636 const int numberOfDropDigits = -exponent(); | 636 const int numberOfDropDigits = -exponent(); |
| 637 if (numberOfDigits <= numberOfDropDigits) | 637 if (numberOfDigits <= numberOfDropDigits) |
| 638 return isPositive() ? Decimal(1) : zero(Positive); | 638 return isPositive() ? Decimal(1) : zero(Positive); |
| 639 | 639 |
| 640 result = scaleDown(result, numberOfDropDigits); | 640 result = scaleDown(result, numberOfDropDigits); |
| 641 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro
pDigits)) | 641 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro
pDigits)) |
| 642 ++result; | 642 ++result; |
| 643 return Decimal(sign(), 0, result); | 643 return Decimal(getSign(), 0, result); |
| 644 } | 644 } |
| 645 | 645 |
| 646 Decimal Decimal::compareTo(const Decimal& rhs) const | 646 Decimal Decimal::compareTo(const Decimal& rhs) const |
| 647 { | 647 { |
| 648 const Decimal result(*this - rhs); | 648 const Decimal result(*this - rhs); |
| 649 switch (result.m_data.formatClass()) { | 649 switch (result.m_data.getFormatClass()) { |
| 650 case EncodedData::ClassInfinity: | 650 case EncodedData::ClassInfinity: |
| 651 return result.isNegative() ? Decimal(-1) : Decimal(1); | 651 return result.isNegative() ? Decimal(-1) : Decimal(1); |
| 652 | 652 |
| 653 case EncodedData::ClassNaN: | 653 case EncodedData::ClassNaN: |
| 654 case EncodedData::ClassNormal: | 654 case EncodedData::ClassNormal: |
| 655 return result; | 655 return result; |
| 656 | 656 |
| 657 case EncodedData::ClassZero: | 657 case EncodedData::ClassZero: |
| 658 return zero(Positive); | 658 return zero(Positive); |
| 659 | 659 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 674 | 674 |
| 675 uint64_t result = m_data.coefficient(); | 675 uint64_t result = m_data.coefficient(); |
| 676 const int numberOfDigits = countDigits(result); | 676 const int numberOfDigits = countDigits(result); |
| 677 const int numberOfDropDigits = -exponent(); | 677 const int numberOfDropDigits = -exponent(); |
| 678 if (numberOfDigits < numberOfDropDigits) | 678 if (numberOfDigits < numberOfDropDigits) |
| 679 return isPositive() ? zero(Positive) : Decimal(-1); | 679 return isPositive() ? zero(Positive) : Decimal(-1); |
| 680 | 680 |
| 681 result = scaleDown(result, numberOfDropDigits); | 681 result = scaleDown(result, numberOfDropDigits); |
| 682 if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro
pDigits)) | 682 if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro
pDigits)) |
| 683 ++result; | 683 ++result; |
| 684 return Decimal(sign(), 0, result); | 684 return Decimal(getSign(), 0, result); |
| 685 } | 685 } |
| 686 | 686 |
| 687 Decimal Decimal::fromDouble(double doubleValue) | 687 Decimal Decimal::fromDouble(double doubleValue) |
| 688 { | 688 { |
| 689 if (std::isfinite(doubleValue)) | 689 if (std::isfinite(doubleValue)) |
| 690 return fromString(String::numberToStringECMAScript(doubleValue)); | 690 return fromString(String::numberToStringECMAScript(doubleValue)); |
| 691 | 691 |
| 692 if (std::isinf(doubleValue)) | 692 if (std::isinf(doubleValue)) |
| 693 return infinity(doubleValue < 0 ? Negative : Positive); | 693 return infinity(doubleValue < 0 ? Negative : Positive); |
| 694 | 694 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 uint64_t result = m_data.coefficient(); | 914 uint64_t result = m_data.coefficient(); |
| 915 const int numberOfDigits = countDigits(result); | 915 const int numberOfDigits = countDigits(result); |
| 916 const int numberOfDropDigits = -exponent(); | 916 const int numberOfDropDigits = -exponent(); |
| 917 if (numberOfDigits < numberOfDropDigits) | 917 if (numberOfDigits < numberOfDropDigits) |
| 918 return zero(Positive); | 918 return zero(Positive); |
| 919 | 919 |
| 920 result = scaleDown(result, numberOfDropDigits - 1); | 920 result = scaleDown(result, numberOfDropDigits - 1); |
| 921 if (result % 10 >= 5) | 921 if (result % 10 >= 5) |
| 922 result += 10; | 922 result += 10; |
| 923 result /= 10; | 923 result /= 10; |
| 924 return Decimal(sign(), 0, result); | 924 return Decimal(getSign(), 0, result); |
| 925 } | 925 } |
| 926 | 926 |
| 927 double Decimal::toDouble() const | 927 double Decimal::toDouble() const |
| 928 { | 928 { |
| 929 if (isFinite()) { | 929 if (isFinite()) { |
| 930 bool valid; | 930 bool valid; |
| 931 const double doubleValue = toString().toDouble(&valid); | 931 const double doubleValue = toString().toDouble(&valid); |
| 932 return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN(); | 932 return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN(); |
| 933 } | 933 } |
| 934 | 934 |
| 935 if (isInfinity()) | 935 if (isInfinity()) |
| 936 return isNegative() ? -std::numeric_limits<double>::infinity() : std::nu
meric_limits<double>::infinity(); | 936 return isNegative() ? -std::numeric_limits<double>::infinity() : std::nu
meric_limits<double>::infinity(); |
| 937 | 937 |
| 938 return std::numeric_limits<double>::quiet_NaN(); | 938 return std::numeric_limits<double>::quiet_NaN(); |
| 939 } | 939 } |
| 940 | 940 |
| 941 String Decimal::toString() const | 941 String Decimal::toString() const |
| 942 { | 942 { |
| 943 switch (m_data.formatClass()) { | 943 switch (m_data.getFormatClass()) { |
| 944 case EncodedData::ClassInfinity: | 944 case EncodedData::ClassInfinity: |
| 945 return sign() ? "-Infinity" : "Infinity"; | 945 return getSign() ? "-Infinity" : "Infinity"; |
| 946 | 946 |
| 947 case EncodedData::ClassNaN: | 947 case EncodedData::ClassNaN: |
| 948 return "NaN"; | 948 return "NaN"; |
| 949 | 949 |
| 950 case EncodedData::ClassNormal: | 950 case EncodedData::ClassNormal: |
| 951 case EncodedData::ClassZero: | 951 case EncodedData::ClassZero: |
| 952 break; | 952 break; |
| 953 | 953 |
| 954 default: | 954 default: |
| 955 ASSERT_NOT_REACHED(); | 955 ASSERT_NOT_REACHED(); |
| 956 return ""; | 956 return ""; |
| 957 } | 957 } |
| 958 | 958 |
| 959 StringBuilder builder; | 959 StringBuilder builder; |
| 960 if (sign()) | 960 if (getSign()) |
| 961 builder.append('-'); | 961 builder.append('-'); |
| 962 | 962 |
| 963 int originalExponent = exponent(); | 963 int originalExponent = exponent(); |
| 964 uint64_t coefficient = m_data.coefficient(); | 964 uint64_t coefficient = m_data.coefficient(); |
| 965 | 965 |
| 966 if (originalExponent < 0) { | 966 if (originalExponent < 0) { |
| 967 const int maxDigits = DBL_DIG; | 967 const int maxDigits = DBL_DIG; |
| 968 uint64_t lastDigit = 0; | 968 uint64_t lastDigit = 0; |
| 969 while (countDigits(coefficient) > maxDigits) { | 969 while (countDigits(coefficient) > maxDigits) { |
| 970 lastDigit = coefficient % 10; | 970 lastDigit = coefficient % 10; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 } | 1022 } |
| 1023 return builder.toString(); | 1023 return builder.toString(); |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 Decimal Decimal::zero(Sign sign) | 1026 Decimal Decimal::zero(Sign sign) |
| 1027 { | 1027 { |
| 1028 return Decimal(EncodedData(sign, EncodedData::ClassZero)); | 1028 return Decimal(EncodedData(sign, EncodedData::ClassZero)); |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 } // namespace blink | 1031 } // namespace blink |
| OLD | NEW |