Returns the result of dividing p by q, rounding using the specified RoundingMode. @throws ArithmeticException if q == 0, or if mode == UNNECESSARY and a is not an integer multiple of b
(int p, int q, RoundingMode mode)
| 321 | */ |
| 322 | |
| 323 | @SuppressWarnings("fallthrough") |
| 324 | public static int divide(int p, int q, RoundingMode mode) { |
| 325 | checkNotNull(mode); |
| 326 | if (q == 0) { |
| 327 | throw new ArithmeticException("/ by zero"); // for GWT |
| 328 | } |
| 329 | |
| 330 | int div = p / q; |
| 331 | int rem = p - q * div; // equal to p % q |
| 332 | if (rem == 0) { |
| 333 | return div; |
| 334 | } |
| 335 | |
| 336 | /* |
| 337 | * Normal Java division rounds towards 0, consistently with RoundingMode.DOWN. We just have to |
| 338 | * deal with the cases where rounding towards 0 is wrong, which typically depends on the sign of |
| 339 | * p / q. |
| 340 | * |
| 341 | * signum is 1 if p and q are both nonnegative or both negative, and -1 otherwise. |
| 342 | */ |
| 343 | |
| 344 | int signum = 1 | ((p ^ q) >> (Integer.SIZE - 1)); |
| 345 | boolean increment; |
| 346 | switch (mode) { |
| 347 | case UNNECESSARY: |
| 348 | checkRoundingUnnecessary(rem == 0); |
| 349 | // fall through |
| 350 | case DOWN: |
| 351 | increment = false; |
| 352 | break; |
| 353 | case UP: |
| 354 | increment = true; |
| 355 | break; |
| 356 | case CEILING: |
| 357 | increment = signum > 0; |
| 358 | break; |
| 359 | case FLOOR: |
| 360 | increment = signum < 0; |
| 361 | break; |
| 362 | case HALF_EVEN: |
| 363 | case HALF_DOWN: |
| 364 | case HALF_UP: |
| 365 | int absRem = abs(rem); |
| 366 | int cmpRemToHalfDivisor = absRem - (abs(q) - absRem); |
| 367 | // subtracting two nonnegative ints can't overflow |
| 368 | // cmpRemToHalfDivisor has the same sign as compare(abs(rem), abs(q) / 2). |
| 369 | if (cmpRemToHalfDivisor == 0) { // exactly on the half mark |
| 370 | increment = (mode == HALF_UP || (mode == HALF_EVEN & (div & 1) != 0)); |
| 371 | } else { |
| 372 | increment = cmpRemToHalfDivisor > 0; // closer to the UP value |
| 373 | } |
| 374 | break; |
| 375 | default: |
| 376 | throw new AssertionError(); |
| 377 | } |
| 378 | return increment ? div + signum : div; |
| 379 | } |
| 380 |
no test coverage detected