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