1 /* 2 * Copyright (c) 2003, 2005, 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 /* 24 * @test 25 * @bug 4904082 4917089 6337226 6378503 26 * @summary Tests that integral division and related methods return the proper result and scale. 27 * @author Joseph D. Darcy 28 */ 29 import java.math.*; 30 public class IntegralDivisionTests { 31 32 static int dividetoIntegralValueTests() { 33 int failures = 0; 34 35 // Exact integer quotient should have the same results from 36 // the exact divide and dividetoIntegralValue 37 38 39 // Rounded results 40 BigDecimal [][] moreTestCases = { 41 {new BigDecimal("11003"), new BigDecimal("10"), new BigDecimal("1100")}, 42 {new BigDecimal("11003"), new BigDecimal("1e1"), new BigDecimal("1100.0")}, 43 {new BigDecimal("1e9"), new BigDecimal("1"), new BigDecimal("1e9")}, 44 {new BigDecimal("1e9"), new BigDecimal("1.00"), new BigDecimal("1e9")}, 45 {new BigDecimal("1e9"), new BigDecimal("0.1"), new BigDecimal("1e10")}, 46 {new BigDecimal("10e8"), new BigDecimal("0.1"), new BigDecimal("10e9")}, 47 {new BigDecimal("400e1"), new BigDecimal("5"), new BigDecimal("80e1")}, 48 {new BigDecimal("400e1"), new BigDecimal("4.999999999"), new BigDecimal("8e2")}, 49 {new BigDecimal("40e2"), new BigDecimal("5"), new BigDecimal("8e2")}, 50 {BigDecimal.valueOf(1, Integer.MIN_VALUE), 51 BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)), 52 BigDecimal.valueOf(1, -256)}, 53 }; 54 55 for(BigDecimal [] testCase: moreTestCases) { 56 BigDecimal quotient; 57 if (! (quotient=testCase[0].divideToIntegralValue(testCase[1])).equals(testCase[2]) ){ 58 failures++; 59 // BigDecimal exact = testCase[0].divide(testCase[1]); 60 System.err.println(); 61 System.err.println("dividend = " + testCase[0] + " scale = " + testCase[0].scale()); 62 System.err.println("divisor = " + testCase[1] + " scale = " + testCase[1].scale()); 63 System.err.println("quotient = " + quotient + " scale = " + quotient.scale()); 64 System.err.println("expected = " + testCase[2] + " scale = " + testCase[2].scale()); 65 // System.err.println("exact = " + exact + " scale = " + exact.scale()); 66 } 67 } 68 69 return failures; 70 } 71 72 static int dividetoIntegralValueRoundedTests() { 73 int failures = 0; 74 75 BigDecimal dividend = new BigDecimal("11003"); 76 BigDecimal divisor = new BigDecimal("10"); 77 BigDecimal [] quotients = { // Expected results with precision = 78 new BigDecimal("1100"), // 0 79 null, // 1 80 new BigDecimal("11e2"), // 2 81 new BigDecimal("110e1"), // 3 82 new BigDecimal("1100"), // 4 83 }; 84 failures += divideContextTestPrecs(dividend, divisor, quotients); 85 86 dividend = new BigDecimal("11003"); 87 divisor = new BigDecimal("1e1"); 88 BigDecimal [] quotients2 = { // Expected results with precision = 89 new BigDecimal("1100.0"), // 0 90 null, // 1 91 new BigDecimal("11e2"), // 2 92 new BigDecimal("110e1"), // 3 93 new BigDecimal("1100"), // 4 94 new BigDecimal("1100.0"), // 5 95 }; 96 failures += divideContextTestPrecs(dividend, divisor, quotients2); 97 98 dividend = new BigDecimal("1230000"); 99 divisor = new BigDecimal("100"); 100 BigDecimal [] quotients3 = { // Expected results with precision = 101 new BigDecimal("12300"), // 0 102 null, // 1 103 null, // 2 104 new BigDecimal("123e2"), // 3 105 new BigDecimal("1230e1"), // 4 106 new BigDecimal("12300"), // 5 107 }; 108 failures += divideContextTestPrecs(dividend, divisor, quotients3); 109 110 dividend = new BigDecimal("33"); 111 divisor = new BigDecimal("3"); 112 BigDecimal [] quotients4 = { // Expected results with precision = 113 new BigDecimal("11"), // 0 114 null, // 1 115 new BigDecimal("11"), // 2 116 new BigDecimal("11"), // 3 117 }; 118 failures += divideContextTestPrecs(dividend, divisor, quotients4); 119 120 dividend = new BigDecimal("34"); 121 divisor = new BigDecimal("3"); 122 BigDecimal [] quotients5 = { // Expected results with precision = 123 new BigDecimal("11"), // 0 124 null, // 1 125 new BigDecimal("11"), // 2 126 new BigDecimal("11"), // 3 127 }; 128 failures += divideContextTestPrecs(dividend, divisor, quotients5); 129 130 return failures; 131 } 132 133 static int divideContextTestPrecs(BigDecimal dividend, 134 BigDecimal divisor, 135 BigDecimal[] quotients) 136 { 137 int failures = 0; 138 for(int i = 0; i < quotients.length; i++) { 139 BigDecimal result = null; 140 BigDecimal quotient = quotients[i]; 141 142 try { 143 result = dividend.divideToIntegralValue(divisor, 144 new MathContext(i, RoundingMode.DOWN)); 145 } catch (ArithmeticException e) { 146 if (quotient != null) { 147 failures++; 148 System.err.println(); 149 System.err.println("Unexpected exception:"); 150 System.err.println("dividend = " + dividend + " scale = " + dividend.scale()); 151 System.err.println("divisor = " + divisor + " scale = " + divisor.scale()); 152 System.err.println("expected = " + quotient + " scale = " + quotient.scale()); 153 } 154 } 155 156 if (quotient != null) { 157 if (! result.equals(quotient)) { 158 failures++; 159 System.err.println(); 160 System.err.println("Unexpected result:"); 161 System.err.println("dividend = " + dividend + " scale = " + dividend.scale()); 162 System.err.println("divisor = " + divisor + " scale = " + divisor.scale()); 163 System.err.println("quotient = " + result + " scale = " + result.scale()); 164 System.err.println("expected = " + quotient + " scale = " + quotient.scale()); 165 System.err.println("precision = " + i); 166 } 167 } else { 168 if (result != null) { 169 failures++; 170 System.err.println(); 171 System.err.println("Unexpected unexceptional result:"); 172 System.err.println("dividend = " + dividend + " scale = " + dividend.scale()); 173 System.err.println("divisor = " + divisor + " scale = " + divisor.scale()); 174 System.err.println("quotient = " + result + " scale = " + result.scale()); 175 System.err.println("precision = " + i); 176 } 177 } 178 179 } 180 return failures; 181 } 182 183 184 static int divideContextTests(BigDecimal dividend, 185 BigDecimal divisor, 186 BigDecimal expected, 187 MathContext mc) { 188 int failures = 0; 189 190 failures += divideContextTest(dividend, divisor, expected, mc); 191 failures += divideContextTest(dividend.negate(), divisor.negate(), expected, mc); 192 193 if (expected != null) { 194 failures += divideContextTest(dividend.negate(), divisor, expected.negate(), mc); 195 failures += divideContextTest(dividend, divisor.negate(), expected.negate(), mc); 196 } 197 198 return failures; 199 } 200 201 202 static int divideContextTest(BigDecimal dividend, 203 BigDecimal divisor, 204 BigDecimal expected, 205 MathContext mc) 206 { 207 int failures = 0; 208 209 BigDecimal result = null; 210 211 try { 212 result = dividend.divideToIntegralValue(divisor, mc); 213 } catch (ArithmeticException e) { 214 if (expected != null) { 215 failures++; 216 System.err.println(); 217 System.err.println("Unexpected exception:"); 218 System.err.println("dividend = " + dividend + " scale = " + dividend.scale()); 219 System.err.println("divisor = " + divisor + " scale = " + divisor.scale()); 220 System.err.println("expected = " + expected + " scale = " + expected.scale()); 221 System.err.println("MathContext = " + mc); 222 } 223 } 224 225 if (expected != null) { 226 if (! result.equals(expected)) { 227 failures++; 228 System.err.println(); 229 System.err.println("Unexpected result:"); 230 System.err.println("dividend = " + dividend + " scale = " + dividend.scale()); 231 System.err.println("divisor = " + divisor + " scale = " + divisor.scale()); 232 System.err.println("expected = " + expected + " scale = " + expected.scale()); 233 System.err.println("result = " + result + " scale = " + result.scale()); 234 System.err.println("MathContext = " + mc); 235 } 236 } else { 237 if (result != null) { 238 failures++; 239 System.err.println(); 240 System.err.println("Unexpected unexceptional result:"); 241 System.err.println("dividend = " + dividend + " scale = " + dividend.scale()); 242 System.err.println("divisor = " + divisor + " scale = " + divisor.scale()); 243 System.err.println("quotient = " + result + " scale = " + result.scale()); 244 System.err.println("MathConext = " + mc); 245 } 246 } 247 248 return failures; 249 } 250 251 static int dividetoIntegralValueScalingTests() { 252 int failures = 0; 253 254 BigDecimal dividend = new BigDecimal("123456789000"); 255 BigDecimal divisor = BigDecimal.ONE; 256 BigDecimal expected = new BigDecimal("123456789e3"); 257 MathContext mc = new MathContext(9,RoundingMode.DOWN); 258 failures += divideContextTests(dividend, divisor, expected, mc); 259 260 261 // 100/3 = 33 remainder 1 262 int [] precisions = {0, 2, 3, 4}; 263 dividend = new BigDecimal(100); 264 divisor = new BigDecimal(3); 265 expected = new BigDecimal(33); 266 267 for(RoundingMode rm: RoundingMode.values()) 268 for(int precision: precisions) { 269 failures += divideContextTests(dividend, divisor, expected, 270 new MathContext(precision, rm)); 271 } 272 273 // 123000/10 = 12300 remainder 0 274 dividend = new BigDecimal(123000); 275 divisor = new BigDecimal(10); 276 int[] precisions1 = {0, 1, 2, 3, 4, 5}; 277 BigDecimal[] expected1 = { 278 new BigDecimal("12300"), 279 null, 280 null, 281 new BigDecimal("123e2"), 282 new BigDecimal("1230e1"), 283 new BigDecimal("12300"), 284 }; 285 286 for(RoundingMode rm: RoundingMode.values()) 287 for(int i = 0; i < precisions1.length; i++) { 288 failures += divideContextTests(dividend, divisor, 289 expected1[i], 290 new MathContext(precisions1[i], rm)); 291 } 292 293 // 123e3/10 = 123e2 remainder 0 294 dividend = new BigDecimal("123e3"); 295 divisor = new BigDecimal(10); 296 int[] precisions2 = {0, 1, 2, 3, 4, 5}; 297 BigDecimal[] expected2 = { 298 new BigDecimal("123e2"), 299 null, 300 null, 301 new BigDecimal("123e2"), 302 new BigDecimal("123e2"), 303 new BigDecimal("123e2"), 304 }; 305 306 for(RoundingMode rm: RoundingMode.values()) 307 for(int i = 0; i < precisions2.length; i++) { 308 failures += divideContextTests(dividend, divisor, 309 expected2[i], 310 new MathContext(precisions2[i], rm)); 311 } 312 313 314 // 123000/1e1 = 12300.0 remainder 0 315 dividend = new BigDecimal("123000"); 316 divisor = new BigDecimal("1e1"); 317 int[] precisions3 = {0, 1, 2, 3, 4, 5, 6}; 318 BigDecimal[] expected3 = { 319 new BigDecimal("12300.0"), 320 null, 321 null, 322 new BigDecimal("123e2"), 323 new BigDecimal("1230e1"), 324 new BigDecimal("12300"), 325 new BigDecimal("12300.0"), 326 }; 327 328 for(RoundingMode rm: RoundingMode.values()) 329 for(int i = 0; i < precisions3.length; i++) { 330 failures += divideContextTests(dividend, divisor, 331 expected3[i], 332 new MathContext(precisions3[i], rm)); 333 } 334 335 336 337 return failures; 338 } 339 340 public static void main(String argv[]) { 341 int failures = 0; 342 343 failures += dividetoIntegralValueTests(); 344 failures += dividetoIntegralValueRoundedTests(); 345 failures += dividetoIntegralValueScalingTests(); 346 347 if (failures > 0) { 348 System.err.println("Encountered " + failures + 349 " failures while testing integral division."); 350 throw new RuntimeException(); 351 } 352 } 353 }