1/* 2 * Copyright (c) 2012, 2016, 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 24import java.math.BigDecimal; 25import java.math.RoundingMode; 26 27/** 28 * @test Test Math and StrictMath Floor Div / Modulo operations. 29 * @bug 6282196 30 * @summary Basic tests for Floor division and modulo methods for both Math 31 * and StrictMath for int and long datatypes. 32 */ 33public class DivModTests { 34 35 /** 36 * The count of test errors. 37 */ 38 private static int errors = 0; 39 40 /** 41 * @param args the command line arguments are unused 42 */ 43 public static void main(String[] args) { 44 errors = 0; 45 testIntFloorDivMod(); 46 testLongFloorDivMod(); 47 48 if (errors > 0) { 49 throw new RuntimeException(errors + " errors found in DivMod methods."); 50 } 51 } 52 53 /** 54 * Report a test failure and increment the error count. 55 * @param message the formatting string 56 * @param args the variable number of arguments for the message. 57 */ 58 static void fail(String message, Object... args) { 59 errors++; 60 System.out.printf(message, args); 61 } 62 63 /** 64 * Test the integer floorDiv and floorMod methods. 65 * Math and StrictMath tested and the same results are expected for both. 66 */ 67 static void testIntFloorDivMod() { 68 testIntFloorDivMod(4, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException 69 testIntFloorDivMod(4, 3, 1, 1); 70 testIntFloorDivMod(3, 3, 1, 0); 71 testIntFloorDivMod(2, 3, 0, 2); 72 testIntFloorDivMod(1, 3, 0, 1); 73 testIntFloorDivMod(0, 3, 0, 0); 74 testIntFloorDivMod(4, -3, -2, -2); 75 testIntFloorDivMod(3, -3, -1, 0); 76 testIntFloorDivMod(2, -3, -1, -1); 77 testIntFloorDivMod(1, -3, -1, -2); 78 testIntFloorDivMod(0, -3, 0, 0); 79 testIntFloorDivMod(-1, 3, -1, 2); 80 testIntFloorDivMod(-2, 3, -1, 1); 81 testIntFloorDivMod(-3, 3, -1, 0); 82 testIntFloorDivMod(-4, 3, -2, 2); 83 testIntFloorDivMod(-1, -3, 0, -1); 84 testIntFloorDivMod(-2, -3, 0, -2); 85 testIntFloorDivMod(-3, -3, 1, 0); 86 testIntFloorDivMod(-4, -3, 1, -1); 87 testIntFloorDivMod(Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0); 88 testIntFloorDivMod(Integer.MAX_VALUE, -1, -Integer.MAX_VALUE, 0); 89 testIntFloorDivMod(Integer.MAX_VALUE, 3, 715827882, 1); 90 testIntFloorDivMod(Integer.MAX_VALUE - 1, 3, 715827882, 0); 91 testIntFloorDivMod(Integer.MIN_VALUE, 3, -715827883, 1); 92 testIntFloorDivMod(Integer.MIN_VALUE + 1, 3, -715827883, 2); 93 testIntFloorDivMod(Integer.MIN_VALUE + 1, -1, Integer.MAX_VALUE, 0); 94 // Special case of integer overflow 95 testIntFloorDivMod(Integer.MIN_VALUE, -1, Integer.MIN_VALUE, 0); 96 } 97 98 /** 99 * Test FloorDiv and then FloorMod with int data. 100 */ 101 static void testIntFloorDivMod(int x, int y, Object divExpected, Object modExpected) { 102 testIntFloorDiv(x, y, divExpected); 103 testIntFloorMod(x, y, modExpected); 104 } 105 106 /** 107 * Test FloorDiv with int data. 108 */ 109 static void testIntFloorDiv(int x, int y, Object expected) { 110 Object result = doFloorDiv(x, y); 111 if (!resultEquals(result, expected)) { 112 fail("FAIL: Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected); 113 } 114 115 Object strict_result = doStrictFloorDiv(x, y); 116 if (!resultEquals(strict_result, expected)) { 117 fail("FAIL: StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected); 118 } 119 } 120 121 /** 122 * Test FloorMod with int data. 123 */ 124 static void testIntFloorMod(int x, int y, Object expected) { 125 Object result = doFloorMod(x, y); 126 if (!resultEquals(result, expected)) { 127 fail("FAIL: Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected); 128 } 129 130 Object strict_result = doStrictFloorMod(x, y); 131 if (!resultEquals(strict_result, expected)) { 132 fail("FAIL: StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected); 133 } 134 135 try { 136 // Verify result against double precision floor function 137 int tmp = x / y; // Force ArithmeticException for divide by zero 138 double ff = x - Math.floor((double)x / (double)y) * y; 139 int fr = (int)ff; 140 boolean t = (fr == ((Integer)result)); 141 if (!result.equals(fr)) { 142 fail("FAIL: Math.floorMod(%d, %d) = %s differs from Math.floor(x, y): %d%n", x, y, result, fr); 143 } 144 } catch (ArithmeticException ae) { 145 if (y != 0) { 146 fail("FAIL: Math.floorMod(%d, %d); unexpected %s%n", x, y, ae); 147 } 148 } 149 } 150 151 /** 152 * Test the floorDiv and floorMod methods for primitive long. 153 */ 154 static void testLongFloorDivMod() { 155 testLongFloorDivMod(4L, 0L, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException 156 testLongFloorDivMod(4L, 3L, 1L, 1L); 157 testLongFloorDivMod(3L, 3L, 1L, 0L); 158 testLongFloorDivMod(2L, 3L, 0L, 2L); 159 testLongFloorDivMod(1L, 3L, 0L, 1L); 160 testLongFloorDivMod(0L, 3L, 0L, 0L); 161 testLongFloorDivMod(4L, -3L, -2L, -2L); 162 testLongFloorDivMod(3L, -3L, -1L, 0l); 163 testLongFloorDivMod(2L, -3L, -1L, -1L); 164 testLongFloorDivMod(1L, -3L, -1L, -2L); 165 testLongFloorDivMod(0L, -3L, 0L, 0L); 166 testLongFloorDivMod(-1L, 3L, -1L, 2L); 167 testLongFloorDivMod(-2L, 3L, -1L, 1L); 168 testLongFloorDivMod(-3L, 3L, -1L, 0L); 169 testLongFloorDivMod(-4L, 3L, -2L, 2L); 170 testLongFloorDivMod(-1L, -3L, 0L, -1L); 171 testLongFloorDivMod(-2L, -3L, 0L, -2L); 172 testLongFloorDivMod(-3L, -3L, 1L, 0L); 173 testLongFloorDivMod(-4L, -3L, 1L, -1L); 174 175 testLongFloorDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0L); 176 testLongFloorDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0L); 177 testLongFloorDivMod(Long.MAX_VALUE, 3L, Long.MAX_VALUE / 3L, 1L); 178 testLongFloorDivMod(Long.MAX_VALUE - 1L, 3L, (Long.MAX_VALUE - 1L) / 3L, 0L); 179 testLongFloorDivMod(Long.MIN_VALUE, 3L, Long.MIN_VALUE / 3L - 1L, 1L); 180 testLongFloorDivMod(Long.MIN_VALUE + 1L, 3L, Long.MIN_VALUE / 3L - 1L, 2L); 181 testLongFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L); 182 // Special case of integer overflow 183 testLongFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L); 184 } 185 186 /** 187 * Test the long floorDiv and floorMod methods. 188 * Math and StrictMath are tested and the same results are expected for both. 189 */ 190 static void testLongFloorDivMod(long x, long y, Object divExpected, Object modExpected) { 191 testLongFloorDiv(x, y, divExpected); 192 testLongFloorMod(x, y, modExpected); 193 } 194 195 /** 196 * Test FloorDiv with long arguments against expected value. 197 * The expected value is usually a Long but in some cases is 198 * an ArithmeticException. 199 * 200 * @param x dividend 201 * @param y modulus 202 * @param expected expected value, 203 */ 204 static void testLongFloorDiv(long x, long y, Object expected) { 205 Object result = doFloorDiv(x, y); 206 if (!resultEquals(result, expected)) { 207 fail("FAIL: long Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected); 208 } 209 210 Object strict_result = doStrictFloorDiv(x, y); 211 if (!resultEquals(strict_result, expected)) { 212 fail("FAIL: long StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected); 213 } 214 } 215 216 /** 217 * Test FloorMod of long arguments against expected value. 218 * The expected value is usually a Long but in some cases is 219 * an ArithmeticException. 220 * 221 * @param x dividend 222 * @param y modulus 223 * @param expected expected value 224 */ 225 static void testLongFloorMod(long x, long y, Object expected) { 226 Object result = doFloorMod(x, y); 227 if (!resultEquals(result, expected)) { 228 fail("FAIL: long Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected); 229 } 230 231 Object strict_result = doStrictFloorMod(x, y); 232 if (!resultEquals(strict_result, expected)) { 233 fail("FAIL: long StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected); 234 } 235 236 try { 237 // Verify the result against BigDecimal rounding mode. 238 BigDecimal xD = new BigDecimal(x); 239 BigDecimal yD = new BigDecimal(y); 240 BigDecimal resultD = xD.divide(yD, RoundingMode.FLOOR); 241 resultD = resultD.multiply(yD); 242 resultD = xD.subtract(resultD); 243 long fr = resultD.longValue(); 244 if (!result.equals(fr)) { 245 fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr); 246 247 } 248 } catch (ArithmeticException ae) { 249 if (y != 0) { 250 fail("FAIL: long Math.floorMod(%d, %d); unexpected ArithmeticException from bigdecimal"); 251 } 252 } 253 } 254 255 /** 256 * Test the floorDiv and floorMod methods for mixed long and int. 257 */ 258 static void testLongIntFloorDivMod() { 259 testLongIntFloorDivMod(4L, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException 260 testLongIntFloorDivMod(4L, 3, 1L, 1); 261 testLongIntFloorDivMod(3L, 3, 1L, 0); 262 testLongIntFloorDivMod(2L, 3, 0L, 2); 263 testLongIntFloorDivMod(1L, 3, 0L, 1); 264 testLongIntFloorDivMod(0L, 3, 0L, 0); 265 testLongIntFloorDivMod(4L, -3, -2L, -2); 266 testLongIntFloorDivMod(3L, -3, -1L, 0); 267 testLongIntFloorDivMod(2L, -3, -1L, -1); 268 testLongIntFloorDivMod(1L, -3, -1L, -2); 269 testLongIntFloorDivMod(0L, -3, 0L, 0); 270 testLongIntFloorDivMod(-1L, 3, -1L, 2); 271 testLongIntFloorDivMod(-2L, 3, -1L, 1); 272 testLongIntFloorDivMod(-3L, 3, -1L, 0); 273 testLongIntFloorDivMod(-4L, 3, -2L, 2); 274 testLongIntFloorDivMod(-1L, -3, 0L, -1); 275 testLongIntFloorDivMod(-2L, -3, 0L, -2); 276 testLongIntFloorDivMod(-3L, -3, 1L, 0); 277 testLongIntFloorDivMod(-4L, -3, 1L, -1); 278 279 testLongIntFloorDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0L); 280 testLongIntFloorDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0L); 281 testLongIntFloorDivMod(Long.MAX_VALUE, 3, Long.MAX_VALUE / 3L, 1L); 282 testLongIntFloorDivMod(Long.MAX_VALUE - 1L, 3, (Long.MAX_VALUE - 1L) / 3L, 0L); 283 testLongIntFloorDivMod(Long.MIN_VALUE, 3, Long.MIN_VALUE / 3L - 1L, 1L); 284 testLongIntFloorDivMod(Long.MIN_VALUE + 1L, 3, Long.MIN_VALUE / 3L - 1L, 2L); 285 testLongIntFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L); 286 // Special case of integer overflow 287 testLongIntFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L); 288 } 289 290 /** 291 * Test the integer floorDiv and floorMod methods. 292 * Math and StrictMath are tested and the same results are expected for both. 293 */ 294 static void testLongIntFloorDivMod(long x, int y, Object divExpected, Object modExpected) { 295 testLongIntFloorDiv(x, y, divExpected); 296 testLongIntFloorMod(x, y, modExpected); 297 } 298 299 /** 300 * Test FloorDiv with long arguments against expected value. 301 * The expected value is usually a Long but in some cases is 302 * an ArithmeticException. 303 * 304 * @param x dividend 305 * @param y modulus 306 * @param expected expected value, 307 */ 308 static void testLongIntFloorDiv(long x, int y, Object expected) { 309 Object result = doFloorDiv(x, y); 310 if (!resultEquals(result, expected)) { 311 fail("FAIL: long Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected); 312 } 313 314 Object strict_result = doStrictFloorDiv(x, y); 315 if (!resultEquals(strict_result, expected)) { 316 fail("FAIL: long StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected); 317 } 318 } 319 320 /** 321 * Test FloorMod of long arguments against expected value. 322 * The expected value is usually a Long but in some cases is 323 * an ArithmeticException. 324 * 325 * @param x dividend 326 * @param y modulus 327 * @param expected expected value 328 */ 329 static void testLongIntFloorMod(long x, int y, Object expected) { 330 Object result = doFloorMod(x, y); 331 if (!resultEquals(result, expected)) { 332 fail("FAIL: long Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected); 333 } 334 335 Object strict_result = doStrictFloorMod(x, y); 336 if (!resultEquals(strict_result, expected)) { 337 fail("FAIL: long StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected); 338 } 339 340 try { 341 // Verify the result against BigDecimal rounding mode. 342 BigDecimal xD = new BigDecimal(x); 343 BigDecimal yD = new BigDecimal(y); 344 BigDecimal resultD = xD.divide(yD, RoundingMode.FLOOR); 345 resultD = resultD.multiply(yD); 346 resultD = xD.subtract(resultD); 347 long fr = resultD.longValue(); 348 if (!result.equals(fr)) { 349 fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr); 350 351 } 352 } catch (ArithmeticException ae) { 353 if (y != 0) { 354 fail("FAIL: long Math.floorMod(%d, %d); unexpected ArithmeticException from bigdecimal"); 355 } 356 } 357 } 358 359 /** 360 * Invoke floorDiv and return the result or any exception. 361 * @param x the x value 362 * @param y the y value 363 * @return the result Integer or an exception. 364 */ 365 static Object doFloorDiv(int x, int y) { 366 try { 367 return Math.floorDiv(x, y); 368 } catch (ArithmeticException ae) { 369 return ae; 370 } 371 } 372 373 /** 374 * Invoke floorDiv and return the result or any exception. 375 * @param x the x value 376 * @param y the y value 377 * @return the result Integer or an exception. 378 */ 379 static Object doFloorDiv(long x, int y) { 380 try { 381 return Math.floorDiv(x, y); 382 } catch (ArithmeticException ae) { 383 return ae; 384 } 385 } 386 387 /** 388 * Invoke floorDiv and return the result or any exception. 389 * @param x the x value 390 * @param y the y value 391 * @return the result Integer or an exception. 392 */ 393 static Object doFloorDiv(long x, long y) { 394 try { 395 return Math.floorDiv(x, y); 396 } catch (ArithmeticException ae) { 397 return ae; 398 } 399 } 400 401 /** 402 * Invoke floorDiv and return the result or any exception. 403 * @param x the x value 404 * @param y the y value 405 * @return the result Integer or an exception. 406 */ 407 static Object doFloorMod(int x, int y) { 408 try { 409 return Math.floorMod(x, y); 410 } catch (ArithmeticException ae) { 411 return ae; 412 } 413 } 414 415 /** 416 * Invoke floorDiv and return the result or any exception. 417 * @param x the x value 418 * @param y the y value 419 * @return the result Integer or an exception. 420 */ 421 static Object doFloorMod(long x, int y) { 422 try { 423 return Math.floorMod(x, y); 424 } catch (ArithmeticException ae) { 425 return ae; 426 } 427 } 428 429 /** 430 * Invoke floorDiv and return the result or any exception. 431 * @param x the x value 432 * @param y the y value 433 * @return the result Integer or an exception. 434 */ 435 static Object doFloorMod(long x, long y) { 436 try { 437 return Math.floorMod(x, y); 438 } catch (ArithmeticException ae) { 439 return ae; 440 } 441 } 442 443 /** 444 * Invoke floorDiv and return the result or any exception. 445 * @param x the x value 446 * @param y the y value 447 * @return the result Integer or an exception. 448 */ 449 static Object doStrictFloorDiv(int x, int y) { 450 try { 451 return StrictMath.floorDiv(x, y); 452 } catch (ArithmeticException ae) { 453 return ae; 454 } 455 } 456 457 /** 458 * Invoke floorDiv and return the result or any exception. 459 * @param x the x value 460 * @param y the y value 461 * @return the result Integer or an exception. 462 */ 463 static Object doStrictFloorDiv(long x, int y) { 464 try { 465 return StrictMath.floorDiv(x, y); 466 } catch (ArithmeticException ae) { 467 return ae; 468 } 469 } 470 471 /** 472 * Invoke floorDiv and return the result or any exception. 473 * @param x the x value 474 * @param y the y value 475 * @return the result Integer or an exception. 476 */ 477 static Object doStrictFloorDiv(long x, long y) { 478 try { 479 return StrictMath.floorDiv(x, y); 480 } catch (ArithmeticException ae) { 481 return ae; 482 } 483 } 484 485 /** 486 * Invoke floorDiv and return the result or any exception. 487 * @param x the x value 488 * @param y the y value 489 * @return the result Integer or an exception. 490 */ 491 static Object doStrictFloorMod(int x, int y) { 492 try { 493 return StrictMath.floorMod(x, y); 494 } catch (ArithmeticException ae) { 495 return ae; 496 } 497 } 498 499 /** 500 * Invoke floorDiv and return the result or any exception. 501 * @param x the x value 502 * @param y the y value 503 * @return the result Integer or an exception. 504 */ 505 static Object doStrictFloorMod(long x, int y) { 506 try { 507 return StrictMath.floorMod(x, y); 508 } catch (ArithmeticException ae) { 509 return ae; 510 } 511 } 512 513 /** 514 * Invoke floorDiv and return the result or any exception. 515 * @param x the x value 516 * @param y the y value 517 * @return the result Integer or an exception. 518 */ 519 static Object doStrictFloorMod(long x, long y) { 520 try { 521 return StrictMath.floorMod(x, y); 522 } catch (ArithmeticException ae) { 523 return ae; 524 } 525 } 526 527 /** 528 * Returns a boolean by comparing the result and the expected value. 529 * The equals method is not defined for ArithmeticException but it is 530 * desirable to have equals return true if the expected and the result 531 * both threw the same exception (class and message.) 532 * 533 * @param result the result from testing the method 534 * @param expected the expected value 535 * @return true if the result is equal to the expected values; false otherwise. 536 */ 537 static boolean resultEquals(Object result, Object expected) { 538 if (result.getClass() != expected.getClass()) { 539 fail("FAIL: Result type mismatch, %s; expected: %s%n", 540 result.getClass().getName(), expected.getClass().getName()); 541 return false; 542 } 543 544 if (result.equals(expected)) { 545 return true; 546 } 547 // Handle special case to compare ArithmeticExceptions 548 if (result instanceof ArithmeticException && expected instanceof ArithmeticException) { 549 return true; 550 } 551 return false; 552 } 553 554} 555