Returns the base-2 logarithm of x, rounded according to the specified rounding mode. @throws IllegalArgumentException if x <= 0 @throws ArithmeticException if mode is RoundingMode#UNNECESSARY and x is not a power of two
(BigInteger x, RoundingMode mode)
| 92 | */ |
| 93 | |
| 94 | @SuppressWarnings("fallthrough") |
| 95 | // TODO(kevinb): remove after this warning is disabled globally |
| 96 | public static int log2(BigInteger x, RoundingMode mode) { |
| 97 | checkPositive("x", checkNotNull(x)); |
| 98 | int logFloor = x.bitLength() - 1; |
| 99 | switch (mode) { |
| 100 | case UNNECESSARY: |
| 101 | checkRoundingUnnecessary(isPowerOfTwo(x)); // fall through |
| 102 | case DOWN: |
| 103 | case FLOOR: |
| 104 | return logFloor; |
| 105 | case UP: |
| 106 | case CEILING: |
| 107 | return isPowerOfTwo(x) ? logFloor : logFloor + 1; |
| 108 | case HALF_DOWN: |
| 109 | case HALF_UP: |
| 110 | case HALF_EVEN: |
| 111 | if (logFloor < SQRT2_PRECOMPUTE_THRESHOLD) { |
| 112 | BigInteger halfPower = SQRT2_PRECOMPUTED_BITS.shiftRight(SQRT2_PRECOMPUTE_THRESHOLD - logFloor); |
| 113 | if (x.compareTo(halfPower) <= 0) { |
| 114 | return logFloor; |
| 115 | } else { |
| 116 | return logFloor + 1; |
| 117 | } |
| 118 | } |
| 119 | // Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5 |
| 120 | // |
| 121 | // To determine which side of logFloor.5 the logarithm is, |
| 122 | // we compare x^2 to 2^(2 * logFloor + 1). |
| 123 | BigInteger x2 = x.pow(2); |
| 124 | int logX2Floor = x2.bitLength() - 1; |
| 125 | return (logX2Floor < 2 * logFloor + 1) ? logFloor : logFloor + 1; |
| 126 | default: |
| 127 | throw new AssertionError(); |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | /* |
| 132 | * The maximum number of bits in a square root for which we'll precompute an explicit half power |
no test coverage detected