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),
|
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
|
// Constants
|
||||||
/**
|
/**
|
||||||
* The value 0, with a scale of 0.
|
* 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
|
} else if (roundingMode == ROUND_FLOOR) { // Towards -infinity
|
||||||
increment = (qsign < 0);
|
increment = (qsign < 0);
|
||||||
} else {
|
} else {
|
||||||
if (isLongDivision || ldivisor != INFLATED)
|
if (isLongDivision || ldivisor != INFLATED) {
|
||||||
cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
|
if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
|
||||||
else
|
cmpFracHalf = 1; // 2 * r can't fit into long
|
||||||
|
} else {
|
||||||
|
cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
cmpFracHalf = mr.compareHalf(mdivisor);
|
cmpFracHalf = mr.compareHalf(mdivisor);
|
||||||
|
}
|
||||||
if (cmpFracHalf < 0)
|
if (cmpFracHalf < 0)
|
||||||
increment = false; // We're closer to higher digit
|
increment = false; // We're closer to higher digit
|
||||||
else if (cmpFracHalf > 0) // We're closer to lower digit
|
else if (cmpFracHalf > 0) // We're closer to lower digit
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4851776 4907265 6177836
|
* @bug 4851776 4907265 6177836 6876282
|
||||||
* @summary Some tests for the divide methods.
|
* @summary Some tests for the divide methods.
|
||||||
* @author Joseph D. Darcy
|
* @author Joseph D. Darcy
|
||||||
* @compile -source 1.5 DivideTests.java
|
* @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;
|
return failures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user