|
1 diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp |
|
2 --- a/mfbt/decimal/Decimal.cpp |
|
3 +++ b/mfbt/decimal/Decimal.cpp |
|
4 @@ -618,26 +618,26 @@ Decimal::AlignedOperands Decimal::alignO |
|
5 Decimal Decimal::ceiling() const |
|
6 { |
|
7 if (isSpecial()) |
|
8 return *this; |
|
9 |
|
10 if (exponent() >= 0) |
|
11 return *this; |
|
12 |
|
13 - uint64_t result = m_data.coefficient(); |
|
14 - const int numberOfDigits = countDigits(result); |
|
15 + uint64_t coefficient = m_data.coefficient(); |
|
16 + const int numberOfDigits = countDigits(coefficient); |
|
17 const int numberOfDropDigits = -exponent(); |
|
18 if (numberOfDigits < numberOfDropDigits) |
|
19 return isPositive() ? Decimal(1) : zero(Positive); |
|
20 |
|
21 - result = scaleDown(result, numberOfDropDigits - 1); |
|
22 - if (sign() == Positive && result % 10 > 0) |
|
23 - result += 10; |
|
24 - result /= 10; |
|
25 + uint64_t result = scaleDown(coefficient, numberOfDropDigits); |
|
26 + uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); |
|
27 + if (droppedDigits && isPositive()) |
|
28 + result += 1; |
|
29 return Decimal(sign(), 0, result); |
|
30 } |
|
31 |
|
32 Decimal Decimal::compareTo(const Decimal& rhs) const |
|
33 { |
|
34 const Decimal result(*this - rhs); |
|
35 switch (result.m_data.formatClass()) { |
|
36 case EncodedData::ClassInfinity: |
|
37 @@ -660,26 +660,27 @@ Decimal Decimal::compareTo(const Decimal |
|
38 Decimal Decimal::floor() const |
|
39 { |
|
40 if (isSpecial()) |
|
41 return *this; |
|
42 |
|
43 if (exponent() >= 0) |
|
44 return *this; |
|
45 |
|
46 - uint64_t result = m_data.coefficient(); |
|
47 - const int numberOfDigits = countDigits(result); |
|
48 + uint64_t coefficient = m_data.coefficient(); |
|
49 + const int numberOfDigits = countDigits(coefficient); |
|
50 const int numberOfDropDigits = -exponent(); |
|
51 if (numberOfDigits < numberOfDropDigits) |
|
52 return isPositive() ? zero(Positive) : Decimal(-1); |
|
53 |
|
54 - result = scaleDown(result, numberOfDropDigits - 1); |
|
55 - if (isNegative() && result % 10 > 0) |
|
56 - result += 10; |
|
57 - result /= 10; |
|
58 + uint64_t result = scaleDown(coefficient, numberOfDropDigits); |
|
59 + uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); |
|
60 + if (droppedDigits && isNegative()) { |
|
61 + result += 1; |
|
62 + } |
|
63 return Decimal(sign(), 0, result); |
|
64 } |
|
65 |
|
66 Decimal Decimal::fromDouble(double doubleValue) |
|
67 { |
|
68 if (std::isfinite(doubleValue)) |
|
69 return fromString(String::numberToStringECMAScript(doubleValue)); |
|
70 |
|
71 @@ -915,16 +916,18 @@ Decimal Decimal::round() const |
|
72 return *this; |
|
73 |
|
74 uint64_t result = m_data.coefficient(); |
|
75 const int numberOfDigits = countDigits(result); |
|
76 const int numberOfDropDigits = -exponent(); |
|
77 if (numberOfDigits < numberOfDropDigits) |
|
78 return zero(Positive); |
|
79 |
|
80 + // We're implementing round-half-away-from-zero, so we only need the one |
|
81 + // (the most significant) fractional digit: |
|
82 result = scaleDown(result, numberOfDropDigits - 1); |
|
83 if (result % 10 >= 5) |
|
84 result += 10; |
|
85 result /= 10; |
|
86 return Decimal(sign(), 0, result); |
|
87 } |
|
88 |
|
89 double Decimal::toDouble() const |