blob: 1e28e1d7543a315e06538749720759807e0f63c7 [file] [log] [blame]
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4904082 4917089 6337226
* @summary Tests that integral division and related methods return the proper result and scale.
* @author Joseph D. Darcy
*/
import java.math.*;
public class IntegralDivisionTests {
static int dividetoIntegralValueTests() {
int failures = 0;
// Exact integer quotient should have the same results from
// the exact divide and dividetoIntegralValue
// Rounded results
BigDecimal [][] moreTestCases = {
{new BigDecimal("11003"), new BigDecimal("10"), new BigDecimal("1100")},
{new BigDecimal("11003"), new BigDecimal("1e1"), new BigDecimal("1100.0")},
{new BigDecimal("1e9"), new BigDecimal("1"), new BigDecimal("1e9")},
{new BigDecimal("1e9"), new BigDecimal("1.00"), new BigDecimal("1e9")},
{new BigDecimal("1e9"), new BigDecimal("0.1"), new BigDecimal("1e10")},
{new BigDecimal("10e8"), new BigDecimal("0.1"), new BigDecimal("10e9")},
{new BigDecimal("400e1"), new BigDecimal("5"), new BigDecimal("80e1")},
{new BigDecimal("400e1"), new BigDecimal("4.999999999"), new BigDecimal("8e2")},
{new BigDecimal("40e2"), new BigDecimal("5"), new BigDecimal("8e2")},
};
for(BigDecimal [] testCase: moreTestCases) {
BigDecimal quotient;
if (! (quotient=testCase[0].divideToIntegralValue(testCase[1])).equals(testCase[2]) ){
failures++;
// BigDecimal exact = testCase[0].divide(testCase[1]);
System.err.println();
System.err.println("dividend = " + testCase[0] + " scale = " + testCase[0].scale());
System.err.println("divisor = " + testCase[1] + " scale = " + testCase[1].scale());
System.err.println("quotient = " + quotient + " scale = " + quotient.scale());
System.err.println("expected = " + testCase[2] + " scale = " + testCase[2].scale());
// System.err.println("exact = " + exact + " scale = " + exact.scale());
}
}
return failures;
}
static int dividetoIntegralValueRoundedTests() {
int failures = 0;
BigDecimal dividend = new BigDecimal("11003");
BigDecimal divisor = new BigDecimal("10");
BigDecimal [] quotients = { // Expected results with precision =
new BigDecimal("1100"), // 0
null, // 1
new BigDecimal("11e2"), // 2
new BigDecimal("110e1"), // 3
new BigDecimal("1100"), // 4
};
failures += divideContextTestPrecs(dividend, divisor, quotients);
dividend = new BigDecimal("11003");
divisor = new BigDecimal("1e1");
BigDecimal [] quotients2 = { // Expected results with precision =
new BigDecimal("1100.0"), // 0
null, // 1
new BigDecimal("11e2"), // 2
new BigDecimal("110e1"), // 3
new BigDecimal("1100"), // 4
new BigDecimal("1100.0"), // 5
};
failures += divideContextTestPrecs(dividend, divisor, quotients2);
dividend = new BigDecimal("1230000");
divisor = new BigDecimal("100");
BigDecimal [] quotients3 = { // Expected results with precision =
new BigDecimal("12300"), // 0
null, // 1
null, // 2
new BigDecimal("123e2"), // 3
new BigDecimal("1230e1"), // 4
new BigDecimal("12300"), // 5
};
failures += divideContextTestPrecs(dividend, divisor, quotients3);
dividend = new BigDecimal("33");
divisor = new BigDecimal("3");
BigDecimal [] quotients4 = { // Expected results with precision =
new BigDecimal("11"), // 0
null, // 1
new BigDecimal("11"), // 2
new BigDecimal("11"), // 3
};
failures += divideContextTestPrecs(dividend, divisor, quotients4);
dividend = new BigDecimal("34");
divisor = new BigDecimal("3");
BigDecimal [] quotients5 = { // Expected results with precision =
new BigDecimal("11"), // 0
null, // 1
new BigDecimal("11"), // 2
new BigDecimal("11"), // 3
};
failures += divideContextTestPrecs(dividend, divisor, quotients5);
return failures;
}
static int divideContextTestPrecs(BigDecimal dividend,
BigDecimal divisor,
BigDecimal[] quotients)
{
int failures = 0;
for(int i = 0; i < quotients.length; i++) {
BigDecimal result = null;
BigDecimal quotient = quotients[i];
try {
result = dividend.divideToIntegralValue(divisor,
new MathContext(i, RoundingMode.DOWN));
} catch (ArithmeticException e) {
if (quotient != null) {
failures++;
System.err.println();
System.err.println("Unexpected exception:");
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
System.err.println("expected = " + quotient + " scale = " + quotient.scale());
}
}
if (quotient != null) {
if (! result.equals(quotient)) {
failures++;
System.err.println();
System.err.println("Unexpected result:");
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
System.err.println("quotient = " + result + " scale = " + result.scale());
System.err.println("expected = " + quotient + " scale = " + quotient.scale());
System.err.println("precision = " + i);
}
} else {
if (result != null) {
failures++;
System.err.println();
System.err.println("Unexpected unexceptional result:");
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
System.err.println("quotient = " + result + " scale = " + result.scale());
System.err.println("precision = " + i);
}
}
}
return failures;
}
static int divideContextTests(BigDecimal dividend,
BigDecimal divisor,
BigDecimal expected,
MathContext mc) {
int failures = 0;
failures += divideContextTest(dividend, divisor, expected, mc);
failures += divideContextTest(dividend.negate(), divisor.negate(), expected, mc);
if (expected != null) {
failures += divideContextTest(dividend.negate(), divisor, expected.negate(), mc);
failures += divideContextTest(dividend, divisor.negate(), expected.negate(), mc);
}
return failures;
}
static int divideContextTest(BigDecimal dividend,
BigDecimal divisor,
BigDecimal expected,
MathContext mc)
{
int failures = 0;
BigDecimal result = null;
try {
result = dividend.divideToIntegralValue(divisor, mc);
} catch (ArithmeticException e) {
if (expected != null) {
failures++;
System.err.println();
System.err.println("Unexpected exception:");
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
System.err.println("expected = " + expected + " scale = " + expected.scale());
System.err.println("MathContext = " + mc);
}
}
if (expected != null) {
if (! result.equals(expected)) {
failures++;
System.err.println();
System.err.println("Unexpected result:");
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
System.err.println("expected = " + expected + " scale = " + expected.scale());
System.err.println("result = " + result + " scale = " + result.scale());
System.err.println("MathContext = " + mc);
}
} else {
if (result != null) {
failures++;
System.err.println();
System.err.println("Unexpected unexceptional result:");
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
System.err.println("quotient = " + result + " scale = " + result.scale());
System.err.println("MathConext = " + mc);
}
}
return failures;
}
static int dividetoIntegralValueScalingTests() {
int failures = 0;
BigDecimal dividend = new BigDecimal("123456789000");
BigDecimal divisor = BigDecimal.ONE;
BigDecimal expected = new BigDecimal("123456789e3");
MathContext mc = new MathContext(9,RoundingMode.DOWN);
failures += divideContextTests(dividend, divisor, expected, mc);
// 100/3 = 33 remainder 1
int [] precisions = {0, 2, 3, 4};
dividend = new BigDecimal(100);
divisor = new BigDecimal(3);
expected = new BigDecimal(33);
for(RoundingMode rm: RoundingMode.values())
for(int precision: precisions) {
failures += divideContextTests(dividend, divisor, expected,
new MathContext(precision, rm));
}
// 123000/10 = 12300 remainder 0
dividend = new BigDecimal(123000);
divisor = new BigDecimal(10);
int[] precisions1 = {0, 1, 2, 3, 4, 5};
BigDecimal[] expected1 = {
new BigDecimal("12300"),
null,
null,
new BigDecimal("123e2"),
new BigDecimal("1230e1"),
new BigDecimal("12300"),
};
for(RoundingMode rm: RoundingMode.values())
for(int i = 0; i < precisions1.length; i++) {
failures += divideContextTests(dividend, divisor,
expected1[i],
new MathContext(precisions1[i], rm));
}
// 123e3/10 = 123e2 remainder 0
dividend = new BigDecimal("123e3");
divisor = new BigDecimal(10);
int[] precisions2 = {0, 1, 2, 3, 4, 5};
BigDecimal[] expected2 = {
new BigDecimal("123e2"),
null,
null,
new BigDecimal("123e2"),
new BigDecimal("123e2"),
new BigDecimal("123e2"),
};
for(RoundingMode rm: RoundingMode.values())
for(int i = 0; i < precisions2.length; i++) {
failures += divideContextTests(dividend, divisor,
expected2[i],
new MathContext(precisions2[i], rm));
}
// 123000/1e1 = 12300.0 remainder 0
dividend = new BigDecimal("123000");
divisor = new BigDecimal("1e1");
int[] precisions3 = {0, 1, 2, 3, 4, 5, 6};
BigDecimal[] expected3 = {
new BigDecimal("12300.0"),
null,
null,
new BigDecimal("123e2"),
new BigDecimal("1230e1"),
new BigDecimal("12300"),
new BigDecimal("12300.0"),
};
for(RoundingMode rm: RoundingMode.values())
for(int i = 0; i < precisions3.length; i++) {
failures += divideContextTests(dividend, divisor,
expected3[i],
new MathContext(precisions3[i], rm));
}
return failures;
}
public static void main(String argv[]) {
int failures = 0;
failures += dividetoIntegralValueTests();
failures += dividetoIntegralValueRoundedTests();
failures += dividetoIntegralValueScalingTests();
if (failures > 0) {
System.err.println("Encountered " + failures +
" failures while testing integral division.");
throw new RuntimeException();
}
}
}