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