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