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