1 /*
2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 package test.java.math.BigDecimal;
24 
25 /*
26  * @test
27  * @bug 4904082 4917089 6337226 6378503
28  * @summary Tests that integral division and related methods return the proper result and scale.
29  * @author Joseph D. Darcy
30  */
31 
32 import java.math.*;
33 
34 import org.testng.Assert;
35 import org.testng.annotations.Test;
36 
37 // Android-changed: Replace error counting with asserts.
38 public class IntegralDivisionTests {
39 
40     @Test
dividetoIntegralValueTests()41     public void dividetoIntegralValueTests() {
42         // Exact integer quotient should have the same results from
43         // the exact divide and dividetoIntegralValue
44 
45 
46         // Rounded results
47         BigDecimal [][] moreTestCases = {
48             {new BigDecimal("11003"),   new BigDecimal("10"),   new BigDecimal("1100")},
49             {new BigDecimal("11003"),   new BigDecimal("1e1"),  new BigDecimal("1100.0")},
50             {new BigDecimal("1e9"),     new BigDecimal("1"),    new BigDecimal("1e9")},
51             {new BigDecimal("1e9"),     new BigDecimal("1.00"), new BigDecimal("1e9")},
52             {new BigDecimal("1e9"),     new BigDecimal("0.1"),  new BigDecimal("1e10")},
53             {new BigDecimal("10e8"),    new BigDecimal("0.1"),  new BigDecimal("10e9")},
54             {new BigDecimal("400e1"),   new BigDecimal("5"),    new BigDecimal("80e1")},
55             {new BigDecimal("400e1"),   new BigDecimal("4.999999999"),  new BigDecimal("8e2")},
56             {new BigDecimal("40e2"),    new BigDecimal("5"),    new BigDecimal("8e2")},
57             {BigDecimal.valueOf(1, Integer.MIN_VALUE),
58                 BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)),
59                 BigDecimal.valueOf(1, -256)},
60         };
61 
62         for(BigDecimal [] testCase: moreTestCases) {
63             BigDecimal quotient = testCase[0].divideToIntegralValue(testCase[1]);
64             Assert.assertEquals(quotient, testCase[2],
65                 "dividend  = " + testCase[0] + " scale = " + testCase[0].scale() +
66                 " divisor   = " + testCase[1] + " scale = " + testCase[1].scale() +
67                 " quotient  = " + quotient    + " scale = " + quotient.scale() +
68                 " expected  = " + testCase[2] + " scale = " + testCase[2].scale());
69         }
70     }
71 
72     @Test
dividetoIntegralValueRoundedTests()73     public void dividetoIntegralValueRoundedTests() {
74         BigDecimal dividend = new BigDecimal("11003");
75         BigDecimal divisor = new BigDecimal("10");
76         BigDecimal [] quotients = {     // Expected results with precision =
77             new BigDecimal("1100"),     // 0
78             null,                       // 1
79             new BigDecimal("11e2"),     // 2
80             new BigDecimal("110e1"),    // 3
81             new BigDecimal("1100"),     // 4
82         };
83         divideContextTestPrecs(dividend, divisor, quotients);
84 
85         dividend = new BigDecimal("11003");
86         divisor = new BigDecimal("1e1");
87         BigDecimal [] quotients2 = {    // Expected results with precision =
88             new BigDecimal("1100.0"),   // 0
89             null,                       // 1
90             new BigDecimal("11e2"),     // 2
91             new BigDecimal("110e1"),    // 3
92             new BigDecimal("1100"),     // 4
93             new BigDecimal("1100.0"),   // 5
94         };
95         divideContextTestPrecs(dividend, divisor, quotients2);
96 
97         dividend = new BigDecimal("1230000");
98         divisor = new BigDecimal("100");
99         BigDecimal [] quotients3 = {    // Expected results with precision =
100             new BigDecimal("12300"),    // 0
101             null,                       // 1
102             null,                       // 2
103             new BigDecimal("123e2"),    // 3
104             new BigDecimal("1230e1"),   // 4
105             new BigDecimal("12300"),    // 5
106         };
107         divideContextTestPrecs(dividend, divisor, quotients3);
108 
109         dividend = new BigDecimal("33");
110         divisor  = new BigDecimal("3");
111         BigDecimal [] quotients4 = {    // Expected results with precision =
112             new BigDecimal("11"),       // 0
113             null,                       // 1
114             new BigDecimal("11"),       // 2
115             new BigDecimal("11"),       // 3
116         };
117         divideContextTestPrecs(dividend, divisor, quotients4);
118 
119         dividend = new BigDecimal("34");
120         divisor  = new BigDecimal("3");
121         BigDecimal [] quotients5 = {    // Expected results with precision =
122             new BigDecimal("11"),       // 0
123             null,                       // 1
124             new BigDecimal("11"),       // 2
125             new BigDecimal("11"),       // 3
126         };
127         divideContextTestPrecs(dividend, divisor, quotients5);
128     }
129 
divideContextTestPrecs(BigDecimal dividend, BigDecimal divisor, BigDecimal[] quotients)130     static void divideContextTestPrecs(BigDecimal dividend,
131                                       BigDecimal divisor,
132                                       BigDecimal[] quotients) {
133         for(int i = 0; i < quotients.length; i++) {
134             BigDecimal result = null;
135             BigDecimal quotient = quotients[i];
136 
137             try {
138                 result = dividend.divideToIntegralValue(divisor,
139                                                         new MathContext(i, RoundingMode.DOWN));
140             } catch (ArithmeticException e) {
141                 if (quotient != null) {
142                     Assert.fail("Unexpected exception:" +
143                             " dividend  = " + dividend     + " scale = " + dividend.scale() +
144                             " divisor   = " + divisor      + " scale = " + divisor.scale() +
145                             " expected  = " + quotient     + " scale = " + quotient.scale());
146                 }
147             }
148 
149             if (quotient != null) {
150                 Assert.assertEquals(quotient, result, "Unexpected result: " +
151                     " dividend  = " + dividend     + " scale = " + dividend.scale() +
152                     " divisor   = " + divisor      + " scale = " + divisor.scale() +
153                     " quotient  = " + result       + " scale = " + result.scale() +
154                     " expected  = " + quotient     + " scale = " + quotient.scale() +
155                     " precision = " + i);
156             } else {
157                 if (result != null) {
158                     Assert.fail("Unexpected unexceptional result:" +
159                     " dividend  = " + dividend     + " scale = " + dividend.scale() +
160                     " divisor   = " + divisor      + " scale = " + divisor.scale() +
161                     " quotient  = " + result       + " scale = " + result.scale() +
162                     " precision = " + i);
163                 }
164             }
165         }
166     }
167 
168 
divideContextTests(BigDecimal dividend, BigDecimal divisor, BigDecimal expected, MathContext mc)169     static void divideContextTests(BigDecimal dividend,
170                                   BigDecimal divisor,
171                                   BigDecimal expected,
172                                   MathContext mc) {
173         divideContextTest(dividend,              divisor,          expected,                mc);
174         divideContextTest(dividend.negate(),     divisor.negate(), expected,                mc);
175 
176         if (expected != null) {
177             divideContextTest(dividend.negate(), divisor,          expected.negate(),       mc);
178             divideContextTest(dividend,          divisor.negate(), expected.negate(),       mc);
179         }
180     }
181 
182 
divideContextTest(BigDecimal dividend, BigDecimal divisor, BigDecimal expected, MathContext mc)183     static void divideContextTest(BigDecimal dividend,
184                                  BigDecimal divisor,
185                                  BigDecimal expected,
186                                  MathContext mc) {
187         BigDecimal result = null;
188 
189         try {
190             result = dividend.divideToIntegralValue(divisor, mc);
191         } catch (ArithmeticException e) {
192             if (expected != null) {
193                 Assert.fail("Unexpected exception:" +
194                         " dividend  = " + dividend     + " scale = " + dividend.scale() +
195                         " divisor   = " + divisor      + " scale = " + divisor.scale() +
196                         " expected  = " + expected     + " scale = " + expected.scale() +
197                         " MathContext  = " + mc);
198             }
199         }
200 
201         if (expected != null) {
202             Assert.assertEquals(result, expected, "Unexpected result:" +
203                     " dividend  = " + dividend     + " scale = " + dividend.scale() +
204                     " divisor   = " + divisor      + " scale = " + divisor.scale() +
205                     " expected  = " + expected     + " scale = " + expected.scale() +
206                     " result    = " + result       + " scale = " + result.scale() +
207                     " MathContext  = " + mc);
208         } else {
209             if (result != null) {
210                 Assert.fail("Unexpected unexceptional result:" +
211                     "dividend  = " + dividend + " scale = " + dividend.scale() +
212                     "divisor   = " + divisor + " scale = " + divisor.scale() +
213                     "quotient  = " + result + " scale = " + result.scale() +
214                     "MathConext = " + mc);
215             }
216         }
217     }
218 
219     @Test
dividetoIntegralValueScalingTests()220     public void dividetoIntegralValueScalingTests() {
221         BigDecimal dividend = new BigDecimal("123456789000");
222         BigDecimal divisor = BigDecimal.ONE;
223         BigDecimal expected = new BigDecimal("123456789e3");
224         MathContext mc = new MathContext(9,RoundingMode.DOWN);
225         divideContextTests(dividend, divisor, expected, mc);
226 
227 
228         // 100/3 = 33 remainder 1
229         int [] precisions = {0, 2, 3, 4};
230         dividend = new BigDecimal(100);
231         divisor  = new BigDecimal(3);
232         expected = new BigDecimal(33);
233 
234         for(RoundingMode rm: RoundingMode.values())
235             for(int precision: precisions) {
236                 divideContextTests(dividend, divisor, expected, new MathContext(precision, rm));
237             }
238 
239         // 123000/10 = 12300 remainder 0
240         dividend = new BigDecimal(123000);
241         divisor  = new BigDecimal(10);
242         int[] precisions1 = {0, 1, 2, 3, 4, 5};
243         BigDecimal[] expected1 = {
244             new BigDecimal("12300"),
245             null,
246             null,
247             new BigDecimal("123e2"),
248             new BigDecimal("1230e1"),
249             new BigDecimal("12300"),
250         };
251 
252         for(RoundingMode rm: RoundingMode.values())
253             for(int i = 0; i < precisions1.length; i++) {
254                 divideContextTests(dividend, divisor,
255                                                expected1[i],
256                                                new MathContext(precisions1[i], rm));
257             }
258 
259         // 123e3/10 = 123e2 remainder 0
260         dividend = new BigDecimal("123e3");
261         divisor  = new BigDecimal(10);
262         int[] precisions2 = {0, 1, 2, 3, 4, 5};
263         BigDecimal[] expected2 = {
264             new BigDecimal("123e2"),
265             null,
266             null,
267             new BigDecimal("123e2"),
268             new BigDecimal("123e2"),
269             new BigDecimal("123e2"),
270         };
271 
272         for(RoundingMode rm: RoundingMode.values())
273             for(int i = 0; i < precisions2.length; i++) {
274                 divideContextTests(dividend, divisor,
275                                                expected2[i],
276                                                new MathContext(precisions2[i], rm));
277             }
278 
279 
280         // 123000/1e1 = 12300.0 remainder 0
281         dividend = new BigDecimal("123000");
282         divisor  = new BigDecimal("1e1");
283         int[] precisions3 = {0, 1, 2, 3, 4, 5, 6};
284         BigDecimal[] expected3 = {
285             new BigDecimal("12300.0"),
286             null,
287             null,
288             new BigDecimal("123e2"),
289             new BigDecimal("1230e1"),
290             new BigDecimal("12300"),
291             new BigDecimal("12300.0"),
292         };
293 
294         for(RoundingMode rm: RoundingMode.values())
295             for(int i = 0; i < precisions3.length; i++) {
296                 divideContextTests(dividend, divisor,
297                                                expected3[i],
298                                                new MathContext(precisions3[i], rm));
299             }
300     }
301 }
302