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