Returns the square root of x, rounded with the specified rounding mode. @throws IllegalArgumentException if x < 0 @throws ArithmeticException if mode is RoundingMode#UNNECESSARY and sqrt(x) is not an integer
(long x, RoundingMode mode)
| 381 | */ |
| 382 | |
| 383 | @GwtIncompatible // TODO |
| 384 | @SuppressWarnings("fallthrough") |
| 385 | public static long sqrt(long x, RoundingMode mode) { |
| 386 | checkNonNegative("x", x); |
| 387 | if (fitsInInt(x)) { |
| 388 | return IntMath.sqrt((int) x, mode); |
| 389 | } |
| 390 | /* |
| 391 | * Let k be the true value of floor(sqrt(x)), so that |
| 392 | * |
| 393 | * k * k <= x < (k + 1) * (k + 1) |
| 394 | * (double) (k * k) <= (double) x <= (double) ((k + 1) * (k + 1)) |
| 395 | * since casting to double is nondecreasing. |
| 396 | * Note that the right-hand inequality is no longer strict. |
| 397 | * Math.sqrt(k * k) <= Math.sqrt(x) <= Math.sqrt((k + 1) * (k + 1)) |
| 398 | * since Math.sqrt is monotonic. |
| 399 | * (long) Math.sqrt(k * k) <= (long) Math.sqrt(x) <= (long) Math.sqrt((k + 1) * (k + 1)) |
| 400 | * since casting to long is monotonic |
| 401 | * k <= (long) Math.sqrt(x) <= k + 1 |
| 402 | * since (long) Math.sqrt(k * k) == k, as checked exhaustively in |
| 403 | * {@link LongMathTest#testSqrtOfPerfectSquareAsDoubleIsPerfect} |
| 404 | */ |
| 405 | |
| 406 | long guess = (long) Math.sqrt(x); |
| 407 | // Note: guess is always <= FLOOR_SQRT_MAX_LONG. |
| 408 | long guessSquared = guess * guess; |
| 409 | // Note (2013-2-26): benchmarks indicate that, inscrutably enough, using if statements is |
| 410 | // faster here than using lessThanBranchFree. |
| 411 | switch (mode) { |
| 412 | case UNNECESSARY: |
| 413 | checkRoundingUnnecessary(guessSquared == x); |
| 414 | return guess; |
| 415 | case FLOOR: |
| 416 | case DOWN: |
| 417 | if (x < guessSquared) { |
| 418 | return guess - 1; |
| 419 | } |
| 420 | return guess; |
| 421 | case CEILING: |
| 422 | case UP: |
| 423 | if (x > guessSquared) { |
| 424 | return guess + 1; |
| 425 | } |
| 426 | return guess; |
| 427 | case HALF_DOWN: |
| 428 | case HALF_UP: |
| 429 | case HALF_EVEN: |
| 430 | long sqrtFloor = guess - ((x < guessSquared) ? 1 : 0); |
| 431 | long halfSquare = sqrtFloor * sqrtFloor + sqrtFloor; |
| 432 | /* |
| 433 | * We wish to test whether or not x <= (sqrtFloor + 0.5)^2 = halfSquare + 0.25. Since both x |
| 434 | * and halfSquare are integers, this is equivalent to testing whether or not x <= |
| 435 | * halfSquare. (We have to deal with overflow, though.) |
| 436 | * |
| 437 | * If we treat halfSquare as an unsigned long, we know that |
| 438 | * sqrtFloor^2 <= x < (sqrtFloor + 1)^2 |
| 439 | * halfSquare - sqrtFloor <= x < halfSquare + sqrtFloor + 1 |
| 440 | * so |x - halfSquare| <= sqrtFloor. Therefore, it's safe to treat x - halfSquare as a |
no test coverage detected