| diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp |
| --- a/mfbt/decimal/Decimal.cpp |
| +++ b/mfbt/decimal/Decimal.cpp |
| @@ -618,26 +618,26 @@ Decimal::AlignedOperands Decimal::alignO |
| Decimal Decimal::ceiling() const |
| { |
| if (isSpecial()) |
| return *this; |
| |
| if (exponent() >= 0) |
| return *this; |
| |
| - uint64_t result = m_data.coefficient(); |
| - const int numberOfDigits = countDigits(result); |
| + uint64_t coefficient = m_data.coefficient(); |
| + const int numberOfDigits = countDigits(coefficient); |
| const int numberOfDropDigits = -exponent(); |
| if (numberOfDigits < numberOfDropDigits) |
| return isPositive() ? Decimal(1) : zero(Positive); |
| |
| - result = scaleDown(result, numberOfDropDigits - 1); |
| - if (sign() == Positive && result % 10 > 0) |
| - result += 10; |
| - result /= 10; |
| + uint64_t result = scaleDown(coefficient, numberOfDropDigits); |
| + uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); |
| + if (droppedDigits && isPositive()) |
| + result += 1; |
| return Decimal(sign(), 0, result); |
| } |
| |
| Decimal Decimal::compareTo(const Decimal& rhs) const |
| { |
| const Decimal result(*this - rhs); |
| switch (result.m_data.formatClass()) { |
| case EncodedData::ClassInfinity: |
| @@ -660,26 +660,27 @@ Decimal Decimal::compareTo(const Decimal |
| Decimal Decimal::floor() const |
| { |
| if (isSpecial()) |
| return *this; |
| |
| if (exponent() >= 0) |
| return *this; |
| |
| - uint64_t result = m_data.coefficient(); |
| - const int numberOfDigits = countDigits(result); |
| + uint64_t coefficient = m_data.coefficient(); |
| + const int numberOfDigits = countDigits(coefficient); |
| const int numberOfDropDigits = -exponent(); |
| if (numberOfDigits < numberOfDropDigits) |
| return isPositive() ? zero(Positive) : Decimal(-1); |
| |
| - result = scaleDown(result, numberOfDropDigits - 1); |
| - if (isNegative() && result % 10 > 0) |
| - result += 10; |
| - result /= 10; |
| + uint64_t result = scaleDown(coefficient, numberOfDropDigits); |
| + uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); |
| + if (droppedDigits && isNegative()) { |
| + result += 1; |
| + } |
| return Decimal(sign(), 0, result); |
| } |
| |
| Decimal Decimal::fromDouble(double doubleValue) |
| { |
| if (std::isfinite(doubleValue)) |
| return fromString(String::numberToStringECMAScript(doubleValue)); |
| |
| @@ -915,16 +916,18 @@ Decimal Decimal::round() const |
| return *this; |
| |
| uint64_t result = m_data.coefficient(); |
| const int numberOfDigits = countDigits(result); |
| const int numberOfDropDigits = -exponent(); |
| if (numberOfDigits < numberOfDropDigits) |
| return zero(Positive); |
| |
| + // We're implementing round-half-away-from-zero, so we only need the one |
| + // (the most significant) fractional digit: |
| result = scaleDown(result, numberOfDropDigits - 1); |
| if (result % 10 >= 5) |
| result += 10; |
| result /= 10; |
| return Decimal(sign(), 0, result); |
| } |
| |
| double Decimal::toDouble() const |