6876282: BigDecimal's divide(BigDecimal bd, RoundingFormat r) produces incorrect result
Reviewed-by: darcy
This commit is contained in:
parent
03e9812175
commit
4b58ee1a37
@ -315,6 +315,10 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
new BigDecimal(BigInteger.ZERO, 0, 15, 1),
|
||||
};
|
||||
|
||||
// Half of Long.MIN_VALUE & Long.MAX_VALUE.
|
||||
private static final long HALF_LONG_MAX_VALUE = Long.MAX_VALUE / 2;
|
||||
private static final long HALF_LONG_MIN_VALUE = Long.MIN_VALUE / 2;
|
||||
|
||||
// Constants
|
||||
/**
|
||||
* The value 0, with a scale of 0.
|
||||
@ -1455,10 +1459,15 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
} else if (roundingMode == ROUND_FLOOR) { // Towards -infinity
|
||||
increment = (qsign < 0);
|
||||
} else {
|
||||
if (isLongDivision || ldivisor != INFLATED)
|
||||
cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
|
||||
else
|
||||
if (isLongDivision || ldivisor != INFLATED) {
|
||||
if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
|
||||
cmpFracHalf = 1; // 2 * r can't fit into long
|
||||
} else {
|
||||
cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
|
||||
}
|
||||
} else {
|
||||
cmpFracHalf = mr.compareHalf(mdivisor);
|
||||
}
|
||||
if (cmpFracHalf < 0)
|
||||
increment = false; // We're closer to higher digit
|
||||
else if (cmpFracHalf > 0) // We're closer to lower digit
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4851776 4907265 6177836
|
||||
* @bug 4851776 4907265 6177836 6876282
|
||||
* @summary Some tests for the divide methods.
|
||||
* @author Joseph D. Darcy
|
||||
* @compile -source 1.5 DivideTests.java
|
||||
@ -328,6 +328,35 @@ public class DivideTests {
|
||||
}
|
||||
}
|
||||
|
||||
// 6876282
|
||||
BigDecimal[][] testCases2 = {
|
||||
// { dividend, divisor, expected quotient }
|
||||
{ new BigDecimal(3090), new BigDecimal(7), new BigDecimal(441) },
|
||||
{ new BigDecimal("309000000000000000000000"), new BigDecimal("700000000000000000000"),
|
||||
new BigDecimal(441) },
|
||||
{ new BigDecimal("962.430000000000"), new BigDecimal("8346463.460000000000"),
|
||||
new BigDecimal("0.000115309916") },
|
||||
{ new BigDecimal("18446744073709551631"), new BigDecimal("4611686018427387909"),
|
||||
new BigDecimal(4) },
|
||||
{ new BigDecimal("18446744073709551630"), new BigDecimal("4611686018427387909"),
|
||||
new BigDecimal(4) },
|
||||
{ new BigDecimal("23058430092136939523"), new BigDecimal("4611686018427387905"),
|
||||
new BigDecimal(5) },
|
||||
{ new BigDecimal("-18446744073709551661"), new BigDecimal("-4611686018427387919"),
|
||||
new BigDecimal(4) },
|
||||
{ new BigDecimal("-18446744073709551660"), new BigDecimal("-4611686018427387919"),
|
||||
new BigDecimal(4) },
|
||||
};
|
||||
|
||||
for (BigDecimal test[] : testCases2) {
|
||||
BigDecimal quo = test[0].divide(test[1], RoundingMode.HALF_UP);
|
||||
if (!quo.equals(test[2])) {
|
||||
failures++;
|
||||
System.err.println("Unexpected quotient from " + test[0] + " / " + test[1] +
|
||||
" rounding mode HALF_UP" +
|
||||
"; expected " + test[2] + " got " + quo);
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user