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