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
(long x, RoundingMode mode)
| 123 | */ |
| 124 | |
| 125 | @SuppressWarnings("fallthrough") |
| 126 | // TODO(kevinb): remove after this warning is disabled globally |
| 127 | public static int log2(long x, RoundingMode mode) { |
| 128 | checkPositive("x", x); |
| 129 | switch (mode) { |
| 130 | case UNNECESSARY: |
| 131 | checkRoundingUnnecessary(isPowerOfTwo(x)); |
| 132 | // fall through |
| 133 | case DOWN: |
| 134 | case FLOOR: |
| 135 | return (Long.SIZE - 1) - Long.numberOfLeadingZeros(x); |
| 136 | case UP: |
| 137 | case CEILING: |
| 138 | return Long.SIZE - Long.numberOfLeadingZeros(x - 1); |
| 139 | case HALF_DOWN: |
| 140 | case HALF_UP: |
| 141 | case HALF_EVEN: |
| 142 | // Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5 |
| 143 | int leadingZeros = Long.numberOfLeadingZeros(x); |
| 144 | long cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros; |
| 145 | // floor(2^(logFloor + 0.5)) |
| 146 | int logFloor = (Long.SIZE - 1) - leadingZeros; |
| 147 | return logFloor + lessThanBranchFree(cmp, x); |
| 148 | default: |
| 149 | throw new AssertionError("impossible"); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | /** The biggest half power of two that fits into an unsigned long */ |
| 154 |
no test coverage detected