mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 02:48:14 -05:00
Update #0 - First Release
This commit is contained in:
470
sources/main/java/com/google/common/math/BigIntegerMath.java
Normal file
470
sources/main/java/com/google/common/math/BigIntegerMath.java
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.math.MathPreconditions.checkNonNegative;
|
||||
import static com.google.common.math.MathPreconditions.checkPositive;
|
||||
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
|
||||
import static java.math.RoundingMode.CEILING;
|
||||
import static java.math.RoundingMode.FLOOR;
|
||||
import static java.math.RoundingMode.HALF_EVEN;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* A class for arithmetic on values of type {@code BigInteger}.
|
||||
*
|
||||
* <p>
|
||||
* The implementations of many methods in this class are based on material from
|
||||
* Henry S. Warren, Jr.'s <i>Hacker's Delight</i>, (Addison Wesley, 2002).
|
||||
*
|
||||
* <p>
|
||||
* Similar functionality for {@code int} and for {@code long} can be found in
|
||||
* {@link IntMath} and {@link LongMath} respectively.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 11.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class BigIntegerMath {
|
||||
/**
|
||||
* Returns {@code true} if {@code x} represents a power of two.
|
||||
*/
|
||||
public static boolean isPowerOfTwo(BigInteger x) {
|
||||
checkNotNull(x);
|
||||
return x.signum() > 0 && x.getLowestSetBit() == x.bitLength() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base-2 logarithm of {@code x}, rounded according to the specified
|
||||
* rounding mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code x} is not a power of two
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
// TODO(kevinb): remove after this warning is disabled globally
|
||||
public static int log2(BigInteger x, RoundingMode mode) {
|
||||
checkPositive("x", checkNotNull(x));
|
||||
int logFloor = x.bitLength() - 1;
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(isPowerOfTwo(x)); // fall through
|
||||
case DOWN:
|
||||
case FLOOR:
|
||||
return logFloor;
|
||||
|
||||
case UP:
|
||||
case CEILING:
|
||||
return isPowerOfTwo(x) ? logFloor : logFloor + 1;
|
||||
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
if (logFloor < SQRT2_PRECOMPUTE_THRESHOLD) {
|
||||
BigInteger halfPower = SQRT2_PRECOMPUTED_BITS.shiftRight(SQRT2_PRECOMPUTE_THRESHOLD - logFloor);
|
||||
if (x.compareTo(halfPower) <= 0) {
|
||||
return logFloor;
|
||||
} else {
|
||||
return logFloor + 1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5
|
||||
*
|
||||
* To determine which side of logFloor.5 the logarithm is, we compare x^2 to
|
||||
* 2^(2 * logFloor + 1).
|
||||
*/
|
||||
BigInteger x2 = x.pow(2);
|
||||
int logX2Floor = x2.bitLength() - 1;
|
||||
return (logX2Floor < 2 * logFloor + 1) ? logFloor : logFloor + 1;
|
||||
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The maximum number of bits in a square root for which we'll precompute an
|
||||
* explicit half power of two. This can be any value, but higher values incur
|
||||
* more class load time and linearly increasing memory consumption.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static final int SQRT2_PRECOMPUTE_THRESHOLD = 256;
|
||||
|
||||
@VisibleForTesting
|
||||
static final BigInteger SQRT2_PRECOMPUTED_BITS = new BigInteger(
|
||||
"16a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b0667322a", 16);
|
||||
|
||||
/**
|
||||
* Returns the base-10 logarithm of {@code x}, rounded according to the
|
||||
* specified rounding mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code x} is not a power of ten
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static int log10(BigInteger x, RoundingMode mode) {
|
||||
checkPositive("x", x);
|
||||
if (fitsInLong(x)) {
|
||||
return LongMath.log10(x.longValue(), mode);
|
||||
}
|
||||
|
||||
int approxLog10 = (int) (log2(x, FLOOR) * LN_2 / LN_10);
|
||||
BigInteger approxPow = BigInteger.TEN.pow(approxLog10);
|
||||
int approxCmp = approxPow.compareTo(x);
|
||||
|
||||
/*
|
||||
* We adjust approxLog10 and approxPow until they're equal to floor(log10(x))
|
||||
* and 10^floor(log10(x)).
|
||||
*/
|
||||
|
||||
if (approxCmp > 0) {
|
||||
/*
|
||||
* The code is written so that even completely incorrect approximations will
|
||||
* still yield the correct answer eventually, but in practice this branch should
|
||||
* almost never be entered, and even then the loop should not run more than
|
||||
* once.
|
||||
*/
|
||||
do {
|
||||
approxLog10--;
|
||||
approxPow = approxPow.divide(BigInteger.TEN);
|
||||
approxCmp = approxPow.compareTo(x);
|
||||
} while (approxCmp > 0);
|
||||
} else {
|
||||
BigInteger nextPow = BigInteger.TEN.multiply(approxPow);
|
||||
int nextCmp = nextPow.compareTo(x);
|
||||
while (nextCmp <= 0) {
|
||||
approxLog10++;
|
||||
approxPow = nextPow;
|
||||
approxCmp = nextCmp;
|
||||
nextPow = BigInteger.TEN.multiply(approxPow);
|
||||
nextCmp = nextPow.compareTo(x);
|
||||
}
|
||||
}
|
||||
|
||||
int floorLog = approxLog10;
|
||||
BigInteger floorPow = approxPow;
|
||||
int floorCmp = approxCmp;
|
||||
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(floorCmp == 0);
|
||||
// fall through
|
||||
case FLOOR:
|
||||
case DOWN:
|
||||
return floorLog;
|
||||
|
||||
case CEILING:
|
||||
case UP:
|
||||
return floorPow.equals(x) ? floorLog : floorLog + 1;
|
||||
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
// Since sqrt(10) is irrational, log10(x) - floorLog can never be exactly 0.5
|
||||
BigInteger x2 = x.pow(2);
|
||||
BigInteger halfPowerSquared = floorPow.pow(2).multiply(BigInteger.TEN);
|
||||
return (x2.compareTo(halfPowerSquared) <= 0) ? floorLog : floorLog + 1;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private static final double LN_10 = Math.log(10);
|
||||
private static final double LN_2 = Math.log(2);
|
||||
|
||||
/**
|
||||
* Returns the square root of {@code x}, rounded with the specified rounding
|
||||
* mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x < 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code sqrt(x)} is not an integer
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static BigInteger sqrt(BigInteger x, RoundingMode mode) {
|
||||
checkNonNegative("x", x);
|
||||
if (fitsInLong(x)) {
|
||||
return BigInteger.valueOf(LongMath.sqrt(x.longValue(), mode));
|
||||
}
|
||||
BigInteger sqrtFloor = sqrtFloor(x);
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(sqrtFloor.pow(2).equals(x)); // fall through
|
||||
case FLOOR:
|
||||
case DOWN:
|
||||
return sqrtFloor;
|
||||
case CEILING:
|
||||
case UP:
|
||||
int sqrtFloorInt = sqrtFloor.intValue();
|
||||
boolean sqrtFloorIsExact = (sqrtFloorInt * sqrtFloorInt == x.intValue()) // fast check mod 2^32
|
||||
&& sqrtFloor.pow(2).equals(x); // slow exact check
|
||||
return sqrtFloorIsExact ? sqrtFloor : sqrtFloor.add(BigInteger.ONE);
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
BigInteger halfSquare = sqrtFloor.pow(2).add(sqrtFloor);
|
||||
/*
|
||||
* We wish to test whether or not x <= (sqrtFloor + 0.5)^2 = halfSquare + 0.25.
|
||||
* Since both x and halfSquare are integers, this is equivalent to testing
|
||||
* whether or not x <= halfSquare.
|
||||
*/
|
||||
return (halfSquare.compareTo(x) >= 0) ? sqrtFloor : sqrtFloor.add(BigInteger.ONE);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@GwtIncompatible("TODO")
|
||||
private static BigInteger sqrtFloor(BigInteger x) {
|
||||
/*
|
||||
* Adapted from Hacker's Delight, Figure 11-1.
|
||||
*
|
||||
* Using DoubleUtils.bigToDouble, getting a double approximation of x is
|
||||
* extremely fast, and then we can get a double approximation of the square
|
||||
* root. Then, we iteratively improve this guess with an application of Newton's
|
||||
* method, which sets guess := (guess + (x / guess)) / 2. This iteration has the
|
||||
* following two properties:
|
||||
*
|
||||
* a) every iteration (except potentially the first) has guess >=
|
||||
* floor(sqrt(x)). This is because guess' is the arithmetic mean of guess and x
|
||||
* / guess, sqrt(x) is the geometric mean, and the arithmetic mean is always
|
||||
* higher than the geometric mean.
|
||||
*
|
||||
* b) this iteration converges to floor(sqrt(x)). In fact, the number of correct
|
||||
* digits doubles with each iteration, so this algorithm takes O(log(digits))
|
||||
* iterations.
|
||||
*
|
||||
* We start out with a double-precision approximation, which may be higher or
|
||||
* lower than the true value. Therefore, we perform at least one Newton
|
||||
* iteration to get a guess that's definitely >= floor(sqrt(x)), and then
|
||||
* continue the iteration until we reach a fixed point.
|
||||
*/
|
||||
BigInteger sqrt0;
|
||||
int log2 = log2(x, FLOOR);
|
||||
if (log2 < Double.MAX_EXPONENT) {
|
||||
sqrt0 = sqrtApproxWithDoubles(x);
|
||||
} else {
|
||||
int shift = (log2 - DoubleUtils.SIGNIFICAND_BITS) & ~1; // even!
|
||||
/*
|
||||
* We have that x / 2^shift < 2^54. Our initial approximation to sqrtFloor(x)
|
||||
* will be 2^(shift/2) * sqrtApproxWithDoubles(x / 2^shift).
|
||||
*/
|
||||
sqrt0 = sqrtApproxWithDoubles(x.shiftRight(shift)).shiftLeft(shift >> 1);
|
||||
}
|
||||
BigInteger sqrt1 = sqrt0.add(x.divide(sqrt0)).shiftRight(1);
|
||||
if (sqrt0.equals(sqrt1)) {
|
||||
return sqrt0;
|
||||
}
|
||||
do {
|
||||
sqrt0 = sqrt1;
|
||||
sqrt1 = sqrt0.add(x.divide(sqrt0)).shiftRight(1);
|
||||
} while (sqrt1.compareTo(sqrt0) < 0);
|
||||
return sqrt0;
|
||||
}
|
||||
|
||||
@GwtIncompatible("TODO")
|
||||
private static BigInteger sqrtApproxWithDoubles(BigInteger x) {
|
||||
return DoubleMath.roundToBigInteger(Math.sqrt(DoubleUtils.bigToDouble(x)), HALF_EVEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of dividing {@code p} by {@code q}, rounding using the
|
||||
* specified {@code RoundingMode}.
|
||||
*
|
||||
* @throws ArithmeticException if {@code q == 0}, or if
|
||||
* {@code mode == UNNECESSARY} and {@code a} is not
|
||||
* an integer multiple of {@code b}
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static BigInteger divide(BigInteger p, BigInteger q, RoundingMode mode) {
|
||||
BigDecimal pDec = new BigDecimal(p);
|
||||
BigDecimal qDec = new BigDecimal(q);
|
||||
return pDec.divide(qDec, 0, mode).toBigIntegerExact();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code n!}, that is, the product of the first {@code n} positive
|
||||
* integers, or {@code 1} if {@code n == 0}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Warning</b>: the result takes <i>O(n log n)</i> space, so use cautiously.
|
||||
*
|
||||
* <p>
|
||||
* This uses an efficient binary recursive algorithm to compute the factorial
|
||||
* with balanced multiplies. It also removes all the 2s from the intermediate
|
||||
* products (shifting them back in at the end).
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}
|
||||
*/
|
||||
public static BigInteger factorial(int n) {
|
||||
checkNonNegative("n", n);
|
||||
|
||||
// If the factorial is small enough, just use LongMath to do it.
|
||||
if (n < LongMath.factorials.length) {
|
||||
return BigInteger.valueOf(LongMath.factorials[n]);
|
||||
}
|
||||
|
||||
// Pre-allocate space for our list of intermediate BigIntegers.
|
||||
int approxSize = IntMath.divide(n * IntMath.log2(n, CEILING), Long.SIZE, CEILING);
|
||||
ArrayList<BigInteger> bignums = new ArrayList<BigInteger>(approxSize);
|
||||
|
||||
// Start from the pre-computed maximum long factorial.
|
||||
int startingNumber = LongMath.factorials.length;
|
||||
long product = LongMath.factorials[startingNumber - 1];
|
||||
// Strip off 2s from this value.
|
||||
int shift = Long.numberOfTrailingZeros(product);
|
||||
product >>= shift;
|
||||
|
||||
// Use floor(log2(num)) + 1 to prevent overflow of multiplication.
|
||||
int productBits = LongMath.log2(product, FLOOR) + 1;
|
||||
int bits = LongMath.log2(startingNumber, FLOOR) + 1;
|
||||
// Check for the next power of two boundary, to save us a CLZ operation.
|
||||
int nextPowerOfTwo = 1 << (bits - 1);
|
||||
|
||||
// Iteratively multiply the longs as big as they can go.
|
||||
for (long num = startingNumber; num <= n; num++) {
|
||||
// Check to see if the floor(log2(num)) + 1 has changed.
|
||||
if ((num & nextPowerOfTwo) != 0) {
|
||||
nextPowerOfTwo <<= 1;
|
||||
bits++;
|
||||
}
|
||||
// Get rid of the 2s in num.
|
||||
int tz = Long.numberOfTrailingZeros(num);
|
||||
long normalizedNum = num >> tz;
|
||||
shift += tz;
|
||||
// Adjust floor(log2(num)) + 1.
|
||||
int normalizedBits = bits - tz;
|
||||
// If it won't fit in a long, then we store off the intermediate product.
|
||||
if (normalizedBits + productBits >= Long.SIZE) {
|
||||
bignums.add(BigInteger.valueOf(product));
|
||||
product = 1;
|
||||
productBits = 0;
|
||||
}
|
||||
product *= normalizedNum;
|
||||
productBits = LongMath.log2(product, FLOOR) + 1;
|
||||
}
|
||||
// Check for leftovers.
|
||||
if (product > 1) {
|
||||
bignums.add(BigInteger.valueOf(product));
|
||||
}
|
||||
// Efficiently multiply all the intermediate products together.
|
||||
return listProduct(bignums).shiftLeft(shift);
|
||||
}
|
||||
|
||||
static BigInteger listProduct(List<BigInteger> nums) {
|
||||
return listProduct(nums, 0, nums.size());
|
||||
}
|
||||
|
||||
static BigInteger listProduct(List<BigInteger> nums, int start, int end) {
|
||||
switch (end - start) {
|
||||
case 0:
|
||||
return BigInteger.ONE;
|
||||
case 1:
|
||||
return nums.get(start);
|
||||
case 2:
|
||||
return nums.get(start).multiply(nums.get(start + 1));
|
||||
case 3:
|
||||
return nums.get(start).multiply(nums.get(start + 1)).multiply(nums.get(start + 2));
|
||||
default:
|
||||
// Otherwise, split the list in half and recursively do this.
|
||||
int m = (end + start) >>> 1;
|
||||
return listProduct(nums, start, m).multiply(listProduct(nums, m, end));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code n} choose {@code k}, also known as the binomial coefficient of
|
||||
* {@code n} and {@code k}, that is, {@code n! / (k! (n - k)!)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Warning</b>: the result can take as much as <i>O(k log n)</i> space.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}, {@code k < 0}, or
|
||||
* {@code k > n}
|
||||
*/
|
||||
public static BigInteger binomial(int n, int k) {
|
||||
checkNonNegative("n", n);
|
||||
checkNonNegative("k", k);
|
||||
checkArgument(k <= n, "k (%s) > n (%s)", k, n);
|
||||
if (k > (n >> 1)) {
|
||||
k = n - k;
|
||||
}
|
||||
if (k < LongMath.biggestBinomials.length && n <= LongMath.biggestBinomials[k]) {
|
||||
return BigInteger.valueOf(LongMath.binomial(n, k));
|
||||
}
|
||||
|
||||
BigInteger accum = BigInteger.ONE;
|
||||
|
||||
long numeratorAccum = n;
|
||||
long denominatorAccum = 1;
|
||||
|
||||
int bits = LongMath.log2(n, RoundingMode.CEILING);
|
||||
|
||||
int numeratorBits = bits;
|
||||
|
||||
for (int i = 1; i < k; i++) {
|
||||
int p = n - i;
|
||||
int q = i + 1;
|
||||
|
||||
// log2(p) >= bits - 1, because p >= n/2
|
||||
|
||||
if (numeratorBits + bits >= Long.SIZE - 1) {
|
||||
// The numerator is as big as it can get without risking overflow.
|
||||
// Multiply numeratorAccum / denominatorAccum into accum.
|
||||
accum = accum.multiply(BigInteger.valueOf(numeratorAccum)).divide(BigInteger.valueOf(denominatorAccum));
|
||||
numeratorAccum = p;
|
||||
denominatorAccum = q;
|
||||
numeratorBits = bits;
|
||||
} else {
|
||||
// We can definitely multiply into the long accumulators without overflowing
|
||||
// them.
|
||||
numeratorAccum *= p;
|
||||
denominatorAccum *= q;
|
||||
numeratorBits += bits;
|
||||
}
|
||||
}
|
||||
return accum.multiply(BigInteger.valueOf(numeratorAccum)).divide(BigInteger.valueOf(denominatorAccum));
|
||||
}
|
||||
|
||||
// Returns true if BigInteger.valueOf(x.longValue()).equals(x).
|
||||
@GwtIncompatible("TODO")
|
||||
static boolean fitsInLong(BigInteger x) {
|
||||
return x.bitLength() <= Long.SIZE - 1;
|
||||
}
|
||||
|
||||
private BigIntegerMath() {
|
||||
}
|
||||
}
|
490
sources/main/java/com/google/common/math/DoubleMath.java
Normal file
490
sources/main/java/com/google/common/math/DoubleMath.java
Normal file
@ -0,0 +1,490 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.math.DoubleUtils.IMPLICIT_BIT;
|
||||
import static com.google.common.math.DoubleUtils.SIGNIFICAND_BITS;
|
||||
import static com.google.common.math.DoubleUtils.getSignificand;
|
||||
import static com.google.common.math.DoubleUtils.isFinite;
|
||||
import static com.google.common.math.DoubleUtils.isNormal;
|
||||
import static com.google.common.math.DoubleUtils.scaleNormalize;
|
||||
import static com.google.common.math.MathPreconditions.checkInRange;
|
||||
import static com.google.common.math.MathPreconditions.checkNonNegative;
|
||||
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.copySign;
|
||||
import static java.lang.Math.getExponent;
|
||||
import static java.lang.Math.log;
|
||||
import static java.lang.Math.rint;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.primitives.Booleans;
|
||||
|
||||
/**
|
||||
* A class for arithmetic on doubles that is not covered by
|
||||
* {@link java.lang.Math}.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 11.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class DoubleMath {
|
||||
/*
|
||||
* This method returns a value y such that rounding y DOWN (towards zero) gives
|
||||
* the same result as rounding x according to the specified mode.
|
||||
*/
|
||||
@GwtIncompatible("#isMathematicalInteger, com.google.common.math.DoubleUtils")
|
||||
static double roundIntermediate(double x, RoundingMode mode) {
|
||||
if (!isFinite(x)) {
|
||||
throw new ArithmeticException("input is infinite or NaN");
|
||||
}
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(isMathematicalInteger(x));
|
||||
return x;
|
||||
|
||||
case FLOOR:
|
||||
if (x >= 0.0 || isMathematicalInteger(x)) {
|
||||
return x;
|
||||
} else {
|
||||
return x - 1.0;
|
||||
}
|
||||
|
||||
case CEILING:
|
||||
if (x <= 0.0 || isMathematicalInteger(x)) {
|
||||
return x;
|
||||
} else {
|
||||
return x + 1.0;
|
||||
}
|
||||
|
||||
case DOWN:
|
||||
return x;
|
||||
|
||||
case UP:
|
||||
if (isMathematicalInteger(x)) {
|
||||
return x;
|
||||
} else {
|
||||
return x + Math.copySign(1.0, x);
|
||||
}
|
||||
|
||||
case HALF_EVEN:
|
||||
return rint(x);
|
||||
|
||||
case HALF_UP: {
|
||||
double z = rint(x);
|
||||
if (abs(x - z) == 0.5) {
|
||||
return x + copySign(0.5, x);
|
||||
} else {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
case HALF_DOWN: {
|
||||
double z = rint(x);
|
||||
if (abs(x - z) == 0.5) {
|
||||
return x;
|
||||
} else {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code int} value that is equal to {@code x} rounded with the
|
||||
* specified rounding mode, if possible.
|
||||
*
|
||||
* @throws ArithmeticException if
|
||||
* <ul>
|
||||
* <li>{@code x} is infinite or NaN
|
||||
* <li>{@code x}, after being rounded to a
|
||||
* mathematical integer using the specified rounding
|
||||
* mode, is either less than
|
||||
* {@code Integer.MIN_VALUE} or greater than {@code
|
||||
* Integer.MAX_VALUE}
|
||||
* <li>{@code x} is not a mathematical integer and
|
||||
* {@code mode} is {@link RoundingMode#UNNECESSARY}
|
||||
* </ul>
|
||||
*/
|
||||
@GwtIncompatible("#roundIntermediate")
|
||||
public static int roundToInt(double x, RoundingMode mode) {
|
||||
double z = roundIntermediate(x, mode);
|
||||
checkInRange(z > MIN_INT_AS_DOUBLE - 1.0 & z < MAX_INT_AS_DOUBLE + 1.0);
|
||||
return (int) z;
|
||||
}
|
||||
|
||||
private static final double MIN_INT_AS_DOUBLE = -0x1p31;
|
||||
private static final double MAX_INT_AS_DOUBLE = 0x1p31 - 1.0;
|
||||
|
||||
/**
|
||||
* Returns the {@code long} value that is equal to {@code x} rounded with the
|
||||
* specified rounding mode, if possible.
|
||||
*
|
||||
* @throws ArithmeticException if
|
||||
* <ul>
|
||||
* <li>{@code x} is infinite or NaN
|
||||
* <li>{@code x}, after being rounded to a
|
||||
* mathematical integer using the specified rounding
|
||||
* mode, is either less than {@code Long.MIN_VALUE}
|
||||
* or greater than {@code
|
||||
* Long.MAX_VALUE}
|
||||
* <li>{@code x} is not a mathematical integer and
|
||||
* {@code mode} is {@link RoundingMode#UNNECESSARY}
|
||||
* </ul>
|
||||
*/
|
||||
@GwtIncompatible("#roundIntermediate")
|
||||
public static long roundToLong(double x, RoundingMode mode) {
|
||||
double z = roundIntermediate(x, mode);
|
||||
checkInRange(MIN_LONG_AS_DOUBLE - z < 1.0 & z < MAX_LONG_AS_DOUBLE_PLUS_ONE);
|
||||
return (long) z;
|
||||
}
|
||||
|
||||
private static final double MIN_LONG_AS_DOUBLE = -0x1p63;
|
||||
/*
|
||||
* We cannot store Long.MAX_VALUE as a double without losing precision. Instead,
|
||||
* we store Long.MAX_VALUE + 1 == -Long.MIN_VALUE, and then offset all
|
||||
* comparisons by 1.
|
||||
*/
|
||||
private static final double MAX_LONG_AS_DOUBLE_PLUS_ONE = 0x1p63;
|
||||
|
||||
/**
|
||||
* Returns the {@code BigInteger} value that is equal to {@code x} rounded with
|
||||
* the specified rounding mode, if possible.
|
||||
*
|
||||
* @throws ArithmeticException if
|
||||
* <ul>
|
||||
* <li>{@code x} is infinite or NaN
|
||||
* <li>{@code x} is not a mathematical integer and
|
||||
* {@code mode} is {@link RoundingMode#UNNECESSARY}
|
||||
* </ul>
|
||||
*/
|
||||
@GwtIncompatible("#roundIntermediate, java.lang.Math.getExponent, " + "com.google.common.math.DoubleUtils")
|
||||
public static BigInteger roundToBigInteger(double x, RoundingMode mode) {
|
||||
x = roundIntermediate(x, mode);
|
||||
if (MIN_LONG_AS_DOUBLE - x < 1.0 & x < MAX_LONG_AS_DOUBLE_PLUS_ONE) {
|
||||
return BigInteger.valueOf((long) x);
|
||||
}
|
||||
int exponent = getExponent(x);
|
||||
long significand = getSignificand(x);
|
||||
BigInteger result = BigInteger.valueOf(significand).shiftLeft(exponent - SIGNIFICAND_BITS);
|
||||
return (x < 0) ? result.negate() : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code x} is exactly equal to {@code 2^k} for some
|
||||
* finite integer {@code k}.
|
||||
*/
|
||||
@GwtIncompatible("com.google.common.math.DoubleUtils")
|
||||
public static boolean isPowerOfTwo(double x) {
|
||||
return x > 0.0 && isFinite(x) && LongMath.isPowerOfTwo(getSignificand(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base 2 logarithm of a double value.
|
||||
*
|
||||
* <p>
|
||||
* Special cases:
|
||||
* <ul>
|
||||
* <li>If {@code x} is NaN or less than zero, the result is NaN.
|
||||
* <li>If {@code x} is positive infinity, the result is positive infinity.
|
||||
* <li>If {@code x} is positive or negative zero, the result is negative
|
||||
* infinity.
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* The computed result is within 1 ulp of the exact result.
|
||||
*
|
||||
* <p>
|
||||
* If the result of this method will be immediately rounded to an {@code int},
|
||||
* {@link #log2(double, RoundingMode)} is faster.
|
||||
*/
|
||||
public static double log2(double x) {
|
||||
return log(x) / LN_2; // surprisingly within 1 ulp according to tests
|
||||
}
|
||||
|
||||
private static final double LN_2 = log(2);
|
||||
|
||||
/**
|
||||
* Returns the base 2 logarithm of a double value, rounded with the specified
|
||||
* rounding mode to an {@code int}.
|
||||
*
|
||||
* <p>
|
||||
* Regardless of the rounding mode, this is faster than {@code (int) log2(x)}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0.0}, {@code x} is NaN, or
|
||||
* {@code x} is infinite
|
||||
*/
|
||||
@GwtIncompatible("java.lang.Math.getExponent, com.google.common.math.DoubleUtils")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static int log2(double x, RoundingMode mode) {
|
||||
checkArgument(x > 0.0 && isFinite(x), "x must be positive and finite");
|
||||
int exponent = getExponent(x);
|
||||
if (!isNormal(x)) {
|
||||
return log2(x * IMPLICIT_BIT, mode) - SIGNIFICAND_BITS;
|
||||
// Do the calculation on a normal value.
|
||||
}
|
||||
// x is positive, finite, and normal
|
||||
boolean increment;
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(isPowerOfTwo(x));
|
||||
// fall through
|
||||
case FLOOR:
|
||||
increment = false;
|
||||
break;
|
||||
case CEILING:
|
||||
increment = !isPowerOfTwo(x);
|
||||
break;
|
||||
case DOWN:
|
||||
increment = exponent < 0 & !isPowerOfTwo(x);
|
||||
break;
|
||||
case UP:
|
||||
increment = exponent >= 0 & !isPowerOfTwo(x);
|
||||
break;
|
||||
case HALF_DOWN:
|
||||
case HALF_EVEN:
|
||||
case HALF_UP:
|
||||
double xScaled = scaleNormalize(x);
|
||||
// sqrt(2) is irrational, and the spec is relative to the "exact numerical
|
||||
// result,"
|
||||
// so log2(x) is never exactly exponent + 0.5.
|
||||
increment = (xScaled * xScaled) > 2.0;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return increment ? exponent + 1 : exponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code x} represents a mathematical integer.
|
||||
*
|
||||
* <p>
|
||||
* This is equivalent to, but not necessarily implemented as, the expression
|
||||
* {@code
|
||||
* !Double.isNaN(x) && !Double.isInfinite(x) && x == Math.rint(x)}.
|
||||
*/
|
||||
@GwtIncompatible("java.lang.Math.getExponent, com.google.common.math.DoubleUtils")
|
||||
public static boolean isMathematicalInteger(double x) {
|
||||
return isFinite(x)
|
||||
&& (x == 0.0 || SIGNIFICAND_BITS - Long.numberOfTrailingZeros(getSignificand(x)) <= getExponent(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code n!}, that is, the product of the first {@code n} positive
|
||||
* integers, {@code 1} if {@code n == 0}, or e n!}, or
|
||||
* {@link Double#POSITIVE_INFINITY} if {@code n! > Double.MAX_VALUE}.
|
||||
*
|
||||
* <p>
|
||||
* The result is within 1 ulp of the true value.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}
|
||||
*/
|
||||
public static double factorial(int n) {
|
||||
checkNonNegative("n", n);
|
||||
if (n > MAX_FACTORIAL) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
} else {
|
||||
// Multiplying the last (n & 0xf) values into their own accumulator gives a more
|
||||
// accurate
|
||||
// result than multiplying by everySixteenthFactorial[n >> 4] directly.
|
||||
double accum = 1.0;
|
||||
for (int i = 1 + (n & ~0xf); i <= n; i++) {
|
||||
accum *= i;
|
||||
}
|
||||
return accum * everySixteenthFactorial[n >> 4];
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static final int MAX_FACTORIAL = 170;
|
||||
|
||||
@VisibleForTesting
|
||||
static final double[] everySixteenthFactorial = { 0x1.0p0, 0x1.30777758p44, 0x1.956ad0aae33a4p117,
|
||||
0x1.ee69a78d72cb6p202, 0x1.fe478ee34844ap295, 0x1.c619094edabffp394, 0x1.3638dd7bd6347p498,
|
||||
0x1.7cac197cfe503p605, 0x1.1e5dfc140e1e5p716, 0x1.8ce85fadb707ep829, 0x1.95d5f3d928edep945 };
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code a} and {@code b} are within {@code tolerance}
|
||||
* of each other.
|
||||
*
|
||||
* <p>
|
||||
* Technically speaking, this is equivalent to
|
||||
* {@code Math.abs(a - b) <= tolerance || Double.valueOf(a).equals(Double.valueOf(b))}.
|
||||
*
|
||||
* <p>
|
||||
* Notable special cases include:
|
||||
* <ul>
|
||||
* <li>All NaNs are fuzzily equal.
|
||||
* <li>If {@code a == b}, then {@code a} and {@code b} are always fuzzily equal.
|
||||
* <li>Positive and negative zero are always fuzzily equal.
|
||||
* <li>If {@code tolerance} is zero, and neither {@code a} nor {@code b} is NaN,
|
||||
* then {@code a} and {@code b} are fuzzily equal if and only if {@code a == b}.
|
||||
* <li>With {@link Double#POSITIVE_INFINITY} tolerance, all non-NaN values are
|
||||
* fuzzily equal.
|
||||
* <li>With finite tolerance, {@code Double.POSITIVE_INFINITY} and {@code
|
||||
* Double.NEGATIVE_INFINITY} are fuzzily equal only to themselves.</li>
|
||||
*
|
||||
* <p>
|
||||
* This is reflexive and symmetric, but <em>not</em> transitive, so it is
|
||||
* <em>not</em> an equivalence relation and <em>not</em> suitable for use in
|
||||
* {@link Object#equals} implementations.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code tolerance} is {@code < 0} or NaN
|
||||
* @since 13.0
|
||||
*/
|
||||
public static boolean fuzzyEquals(double a, double b, double tolerance) {
|
||||
MathPreconditions.checkNonNegative("tolerance", tolerance);
|
||||
return Math.copySign(a - b, 1.0) <= tolerance
|
||||
// copySign(x, 1.0) is a branch-free version of abs(x), but with different NaN
|
||||
// semantics
|
||||
|| (a == b) // needed to ensure that infinities equal themselves
|
||||
|| (Double.isNaN(a) && Double.isNaN(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares {@code a} and {@code b} "fuzzily," with a tolerance for nearly-equal
|
||||
* values.
|
||||
*
|
||||
* <p>
|
||||
* This method is equivalent to
|
||||
* {@code fuzzyEquals(a, b, tolerance) ? 0 : Double.compare(a, b)}. In
|
||||
* particular, like {@link Double#compare(double, double)}, it treats all NaN
|
||||
* values as equal and greater than all other values (including
|
||||
* {@link Double#POSITIVE_INFINITY}).
|
||||
*
|
||||
* <p>
|
||||
* This is <em>not</em> a total ordering and is <em>not</em> suitable for use in
|
||||
* {@link Comparable#compareTo} implementations. In particular, it is not
|
||||
* transitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code tolerance} is {@code < 0} or NaN
|
||||
* @since 13.0
|
||||
*/
|
||||
public static int fuzzyCompare(double a, double b, double tolerance) {
|
||||
if (fuzzyEquals(a, b, tolerance)) {
|
||||
return 0;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
} else {
|
||||
return Booleans.compare(Double.isNaN(a), Double.isNaN(b));
|
||||
}
|
||||
}
|
||||
|
||||
@GwtIncompatible("com.google.common.math.DoubleUtils")
|
||||
private static final class MeanAccumulator {
|
||||
|
||||
private long count = 0;
|
||||
private double mean = 0.0;
|
||||
|
||||
void add(double value) {
|
||||
checkArgument(isFinite(value));
|
||||
++count;
|
||||
// Art of Computer Programming vol. 2, Knuth, 4.2.2, (15)
|
||||
mean += (value - mean) / count;
|
||||
}
|
||||
|
||||
double mean() {
|
||||
checkArgument(count > 0, "Cannot take mean of 0 values");
|
||||
return mean;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the values. There must be at least one value,
|
||||
* and they must all be finite.
|
||||
*/
|
||||
@GwtIncompatible("MeanAccumulator")
|
||||
public static double mean(double... values) {
|
||||
MeanAccumulator accumulator = new MeanAccumulator();
|
||||
for (double value : values) {
|
||||
accumulator.add(value);
|
||||
}
|
||||
return accumulator.mean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the values. There must be at least one value.
|
||||
* The values will be converted to doubles, which does not cause any loss of
|
||||
* precision for ints.
|
||||
*/
|
||||
@GwtIncompatible("MeanAccumulator")
|
||||
public static double mean(int... values) {
|
||||
MeanAccumulator accumulator = new MeanAccumulator();
|
||||
for (int value : values) {
|
||||
accumulator.add(value);
|
||||
}
|
||||
return accumulator.mean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the values. There must be at least one value.
|
||||
* The values will be converted to doubles, which causes loss of precision for
|
||||
* longs of magnitude over 2^53 (slightly over 9e15).
|
||||
*/
|
||||
@GwtIncompatible("MeanAccumulator")
|
||||
public static double mean(long... values) {
|
||||
MeanAccumulator accumulator = new MeanAccumulator();
|
||||
for (long value : values) {
|
||||
accumulator.add(value);
|
||||
}
|
||||
return accumulator.mean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the values. There must be at least one value,
|
||||
* and they must all be finite. The values will be converted to doubles, which
|
||||
* may cause loss of precision for some numeric types.
|
||||
*/
|
||||
@GwtIncompatible("MeanAccumulator")
|
||||
public static double mean(Iterable<? extends Number> values) {
|
||||
MeanAccumulator accumulator = new MeanAccumulator();
|
||||
for (Number value : values) {
|
||||
accumulator.add(value.doubleValue());
|
||||
}
|
||||
return accumulator.mean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the values. There must be at least one value,
|
||||
* and they must all be finite. The values will be converted to doubles, which
|
||||
* may cause loss of precision for some numeric types.
|
||||
*/
|
||||
@GwtIncompatible("MeanAccumulator")
|
||||
public static double mean(Iterator<? extends Number> values) {
|
||||
MeanAccumulator accumulator = new MeanAccumulator();
|
||||
while (values.hasNext()) {
|
||||
accumulator.add(values.next().doubleValue());
|
||||
}
|
||||
return accumulator.mean();
|
||||
}
|
||||
|
||||
private DoubleMath() {
|
||||
}
|
||||
}
|
148
sources/main/java/com/google/common/math/DoubleUtils.java
Normal file
148
sources/main/java/com/google/common/math/DoubleUtils.java
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static java.lang.Double.MAX_EXPONENT;
|
||||
import static java.lang.Double.MIN_EXPONENT;
|
||||
import static java.lang.Double.POSITIVE_INFINITY;
|
||||
import static java.lang.Double.doubleToRawLongBits;
|
||||
import static java.lang.Double.isNaN;
|
||||
import static java.lang.Double.longBitsToDouble;
|
||||
import static java.lang.Math.getExponent;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Utilities for {@code double} primitives.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
*/
|
||||
final class DoubleUtils {
|
||||
private DoubleUtils() {
|
||||
}
|
||||
|
||||
static double nextDown(double d) {
|
||||
return -Math.nextUp(-d);
|
||||
}
|
||||
|
||||
// The mask for the significand, according to the {@link
|
||||
// Double#doubleToRawLongBits(double)} spec.
|
||||
static final long SIGNIFICAND_MASK = 0x000fffffffffffffL;
|
||||
|
||||
// The mask for the exponent, according to the {@link
|
||||
// Double#doubleToRawLongBits(double)} spec.
|
||||
static final long EXPONENT_MASK = 0x7ff0000000000000L;
|
||||
|
||||
// The mask for the sign, according to the {@link
|
||||
// Double#doubleToRawLongBits(double)} spec.
|
||||
static final long SIGN_MASK = 0x8000000000000000L;
|
||||
|
||||
static final int SIGNIFICAND_BITS = 52;
|
||||
|
||||
static final int EXPONENT_BIAS = 1023;
|
||||
|
||||
/**
|
||||
* The implicit 1 bit that is omitted in significands of normal doubles.
|
||||
*/
|
||||
static final long IMPLICIT_BIT = SIGNIFICAND_MASK + 1;
|
||||
|
||||
static long getSignificand(double d) {
|
||||
checkArgument(isFinite(d), "not a normal value");
|
||||
int exponent = getExponent(d);
|
||||
long bits = doubleToRawLongBits(d);
|
||||
bits &= SIGNIFICAND_MASK;
|
||||
return (exponent == MIN_EXPONENT - 1) ? bits << 1 : bits | IMPLICIT_BIT;
|
||||
}
|
||||
|
||||
static boolean isFinite(double d) {
|
||||
return getExponent(d) <= MAX_EXPONENT;
|
||||
}
|
||||
|
||||
static boolean isNormal(double d) {
|
||||
return getExponent(d) >= MIN_EXPONENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns x scaled by a power of 2 such that it is in the range [1, 2). Assumes
|
||||
* x is positive, normal, and finite.
|
||||
*/
|
||||
static double scaleNormalize(double x) {
|
||||
long significand = doubleToRawLongBits(x) & SIGNIFICAND_MASK;
|
||||
return longBitsToDouble(significand | ONE_BITS);
|
||||
}
|
||||
|
||||
static double bigToDouble(BigInteger x) {
|
||||
// This is an extremely fast implementation of BigInteger.doubleValue(). JDK
|
||||
// patch pending.
|
||||
BigInteger absX = x.abs();
|
||||
int exponent = absX.bitLength() - 1;
|
||||
// exponent == floor(log2(abs(x)))
|
||||
if (exponent < Long.SIZE - 1) {
|
||||
return x.longValue();
|
||||
} else if (exponent > MAX_EXPONENT) {
|
||||
return x.signum() * POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need the top SIGNIFICAND_BITS + 1 bits, including the "implicit" one bit.
|
||||
* To make rounding easier, we pick out the top SIGNIFICAND_BITS + 2 bits, so we
|
||||
* have one to help us round up or down. twiceSignifFloor will contain the top
|
||||
* SIGNIFICAND_BITS + 2 bits, and signifFloor the top SIGNIFICAND_BITS + 1.
|
||||
*
|
||||
* It helps to consider the real number signif = absX * 2^(SIGNIFICAND_BITS -
|
||||
* exponent).
|
||||
*/
|
||||
int shift = exponent - SIGNIFICAND_BITS - 1;
|
||||
long twiceSignifFloor = absX.shiftRight(shift).longValue();
|
||||
long signifFloor = twiceSignifFloor >> 1;
|
||||
signifFloor &= SIGNIFICAND_MASK; // remove the implied bit
|
||||
|
||||
/*
|
||||
* We round up if either the fractional part of signif is strictly greater than
|
||||
* 0.5 (which is true if the 0.5 bit is set and any lower bit is set), or if the
|
||||
* fractional part of signif is >= 0.5 and signifFloor is odd (which is true if
|
||||
* both the 0.5 bit and the 1 bit are set).
|
||||
*/
|
||||
boolean increment = (twiceSignifFloor & 1) != 0 && ((signifFloor & 1) != 0 || absX.getLowestSetBit() < shift);
|
||||
long signifRounded = increment ? signifFloor + 1 : signifFloor;
|
||||
long bits = (long) ((exponent + EXPONENT_BIAS)) << SIGNIFICAND_BITS;
|
||||
bits += signifRounded;
|
||||
/*
|
||||
* If signifRounded == 2^53, we'd need to set all of the significand bits to
|
||||
* zero and add 1 to the exponent. This is exactly the behavior we get from just
|
||||
* adding signifRounded to bits directly. If the exponent is
|
||||
* MAX_DOUBLE_EXPONENT, we round up (correctly) to Double.POSITIVE_INFINITY.
|
||||
*/
|
||||
bits |= x.signum() & SIGN_MASK;
|
||||
return longBitsToDouble(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns its argument if it is non-negative, zero if it is negative.
|
||||
*/
|
||||
static double ensureNonNegative(double value) {
|
||||
checkArgument(!isNaN(value));
|
||||
if (value > 0.0) {
|
||||
return value;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ONE_BITS = doubleToRawLongBits(1.0);
|
||||
}
|
600
sources/main/java/com/google/common/math/IntMath.java
Normal file
600
sources/main/java/com/google/common/math/IntMath.java
Normal file
@ -0,0 +1,600 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.math.MathPreconditions.checkNoOverflow;
|
||||
import static com.google.common.math.MathPreconditions.checkNonNegative;
|
||||
import static com.google.common.math.MathPreconditions.checkPositive;
|
||||
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.min;
|
||||
import static java.math.RoundingMode.HALF_EVEN;
|
||||
import static java.math.RoundingMode.HALF_UP;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* A class for arithmetic on values of type {@code int}. Where possible, methods
|
||||
* are defined and named analogously to their {@code BigInteger} counterparts.
|
||||
*
|
||||
* <p>
|
||||
* The implementations of many methods in this class are based on material from
|
||||
* Henry S. Warren, Jr.'s <i>Hacker's Delight</i>, (Addison Wesley, 2002).
|
||||
*
|
||||
* <p>
|
||||
* Similar functionality for {@code long} and for {@link BigInteger} can be
|
||||
* found in {@link LongMath} and {@link BigIntegerMath} respectively. For other
|
||||
* common operations on {@code int} values, see
|
||||
* {@link com.google.common.primitives.Ints}.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 11.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class IntMath {
|
||||
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, |
|
||||
// instead of &&, ||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code x} represents a power of two.
|
||||
*
|
||||
* <p>
|
||||
* This differs from {@code Integer.bitCount(x) == 1}, because
|
||||
* {@code Integer.bitCount(Integer.MIN_VALUE) == 1}, but
|
||||
* {@link Integer#MIN_VALUE} is not a power of two.
|
||||
*/
|
||||
public static boolean isPowerOfTwo(int x) {
|
||||
return x > 0 & (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 1 if {@code x < y} as unsigned integers, and 0 otherwise. Assumes
|
||||
* that x - y fits into a signed int. The implementation is branch-free, and
|
||||
* benchmarks suggest it is measurably (if narrowly) faster than the
|
||||
* straightforward ternary expression.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static int lessThanBranchFree(int x, int y) {
|
||||
// The double negation is optimized away by normal Java, but is necessary for
|
||||
// GWT
|
||||
// to make sure bit twiddling works as expected.
|
||||
return ~~(x - y) >>> (Integer.SIZE - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base-2 logarithm of {@code x}, rounded according to the specified
|
||||
* rounding mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code x} is not a power of two
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
// TODO(kevinb): remove after this warning is disabled globally
|
||||
public static int log2(int x, RoundingMode mode) {
|
||||
checkPositive("x", x);
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(isPowerOfTwo(x));
|
||||
// fall through
|
||||
case DOWN:
|
||||
case FLOOR:
|
||||
return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(x);
|
||||
|
||||
case UP:
|
||||
case CEILING:
|
||||
return Integer.SIZE - Integer.numberOfLeadingZeros(x - 1);
|
||||
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
// Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5
|
||||
int leadingZeros = Integer.numberOfLeadingZeros(x);
|
||||
int cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros;
|
||||
// floor(2^(logFloor + 0.5))
|
||||
int logFloor = (Integer.SIZE - 1) - leadingZeros;
|
||||
return logFloor + lessThanBranchFree(cmp, x);
|
||||
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/** The biggest half power of two that can fit in an unsigned int. */
|
||||
@VisibleForTesting
|
||||
static final int MAX_POWER_OF_SQRT2_UNSIGNED = 0xB504F333;
|
||||
|
||||
/**
|
||||
* Returns the base-10 logarithm of {@code x}, rounded according to the
|
||||
* specified rounding mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code x} is not a power of ten
|
||||
*/
|
||||
@GwtIncompatible("need BigIntegerMath to adequately test")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static int log10(int x, RoundingMode mode) {
|
||||
checkPositive("x", x);
|
||||
int logFloor = log10Floor(x);
|
||||
int floorPow = powersOf10[logFloor];
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(x == floorPow);
|
||||
// fall through
|
||||
case FLOOR:
|
||||
case DOWN:
|
||||
return logFloor;
|
||||
case CEILING:
|
||||
case UP:
|
||||
return logFloor + lessThanBranchFree(floorPow, x);
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
// sqrt(10) is irrational, so log10(x) - logFloor is never exactly 0.5
|
||||
return logFloor + lessThanBranchFree(halfPowersOf10[logFloor], x);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private static int log10Floor(int x) {
|
||||
/*
|
||||
* Based on Hacker's Delight Fig. 11-5, the two-table-lookup, branch-free
|
||||
* implementation.
|
||||
*
|
||||
* The key idea is that based on the number of leading zeros (equivalently,
|
||||
* floor(log2(x))), we can narrow the possible floor(log10(x)) values to two.
|
||||
* For example, if floor(log2(x)) is 6, then 64 <= x < 128, so floor(log10(x))
|
||||
* is either 1 or 2.
|
||||
*/
|
||||
int y = maxLog10ForLeadingZeros[Integer.numberOfLeadingZeros(x)];
|
||||
/*
|
||||
* y is the higher of the two possible values of floor(log10(x)). If x < 10^y,
|
||||
* then we want the lower of the two possible values, or y - 1, otherwise, we
|
||||
* want y.
|
||||
*/
|
||||
return y - lessThanBranchFree(x, powersOf10[y]);
|
||||
}
|
||||
|
||||
// maxLog10ForLeadingZeros[i] == floor(log10(2^(Long.SIZE - i)))
|
||||
@VisibleForTesting
|
||||
static final byte[] maxLog10ForLeadingZeros = { 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3,
|
||||
2, 2, 2, 1, 1, 1, 0, 0, 0, 0 };
|
||||
|
||||
@VisibleForTesting
|
||||
static final int[] powersOf10 = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||
|
||||
// halfPowersOf10[i] = largest int less than 10^(i + 0.5)
|
||||
@VisibleForTesting
|
||||
static final int[] halfPowersOf10 = { 3, 31, 316, 3162, 31622, 316227, 3162277, 31622776, 316227766,
|
||||
Integer.MAX_VALUE };
|
||||
|
||||
/**
|
||||
* Returns {@code b} to the {@code k}th power. Even if the result overflows, it
|
||||
* will be equal to {@code BigInteger.valueOf(b).pow(k).intValue()}. This
|
||||
* implementation runs in {@code O(log k)} time.
|
||||
*
|
||||
* <p>
|
||||
* Compare {@link #checkedPow}, which throws an {@link ArithmeticException} upon
|
||||
* overflow.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code k < 0}
|
||||
*/
|
||||
@GwtIncompatible("failing tests")
|
||||
public static int pow(int b, int k) {
|
||||
checkNonNegative("exponent", k);
|
||||
switch (b) {
|
||||
case 0:
|
||||
return (k == 0) ? 1 : 0;
|
||||
case 1:
|
||||
return 1;
|
||||
case (-1):
|
||||
return ((k & 1) == 0) ? 1 : -1;
|
||||
case 2:
|
||||
return (k < Integer.SIZE) ? (1 << k) : 0;
|
||||
case (-2):
|
||||
if (k < Integer.SIZE) {
|
||||
return ((k & 1) == 0) ? (1 << k) : -(1 << k);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
// continue below to handle the general case
|
||||
}
|
||||
for (int accum = 1;; k >>= 1) {
|
||||
switch (k) {
|
||||
case 0:
|
||||
return accum;
|
||||
case 1:
|
||||
return b * accum;
|
||||
default:
|
||||
accum *= ((k & 1) == 0) ? 1 : b;
|
||||
b *= b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of {@code x}, rounded with the specified rounding
|
||||
* mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x < 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code sqrt(x)} is not an integer
|
||||
*/
|
||||
@GwtIncompatible("need BigIntegerMath to adequately test")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static int sqrt(int x, RoundingMode mode) {
|
||||
checkNonNegative("x", x);
|
||||
int sqrtFloor = sqrtFloor(x);
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(sqrtFloor * sqrtFloor == x); // fall through
|
||||
case FLOOR:
|
||||
case DOWN:
|
||||
return sqrtFloor;
|
||||
case CEILING:
|
||||
case UP:
|
||||
return sqrtFloor + lessThanBranchFree(sqrtFloor * sqrtFloor, x);
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
int halfSquare = sqrtFloor * sqrtFloor + sqrtFloor;
|
||||
/*
|
||||
* We wish to test whether or not x <= (sqrtFloor + 0.5)^2 = halfSquare + 0.25.
|
||||
* Since both x and halfSquare are integers, this is equivalent to testing
|
||||
* whether or not x <= halfSquare. (We have to deal with overflow, though.)
|
||||
*
|
||||
* If we treat halfSquare as an unsigned int, we know that sqrtFloor^2 <= x <
|
||||
* (sqrtFloor + 1)^2 halfSquare - sqrtFloor <= x < halfSquare + sqrtFloor + 1 so
|
||||
* |x - halfSquare| <= sqrtFloor. Therefore, it's safe to treat x - halfSquare
|
||||
* as a signed int, so lessThanBranchFree is safe for use.
|
||||
*/
|
||||
return sqrtFloor + lessThanBranchFree(halfSquare, x);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private static int sqrtFloor(int x) {
|
||||
// There is no loss of precision in converting an int to a double, according to
|
||||
// http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.2
|
||||
return (int) Math.sqrt(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of dividing {@code p} by {@code q}, rounding using the
|
||||
* specified {@code RoundingMode}.
|
||||
*
|
||||
* @throws ArithmeticException if {@code q == 0}, or if
|
||||
* {@code mode == UNNECESSARY} and {@code a} is not
|
||||
* an integer multiple of {@code b}
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static int divide(int p, int q, RoundingMode mode) {
|
||||
checkNotNull(mode);
|
||||
if (q == 0) {
|
||||
throw new ArithmeticException("/ by zero"); // for GWT
|
||||
}
|
||||
int div = p / q;
|
||||
int rem = p - q * div; // equal to p % q
|
||||
|
||||
if (rem == 0) {
|
||||
return div;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normal Java division rounds towards 0, consistently with RoundingMode.DOWN.
|
||||
* We just have to deal with the cases where rounding towards 0 is wrong, which
|
||||
* typically depends on the sign of p / q.
|
||||
*
|
||||
* signum is 1 if p and q are both nonnegative or both negative, and -1
|
||||
* otherwise.
|
||||
*/
|
||||
int signum = 1 | ((p ^ q) >> (Integer.SIZE - 1));
|
||||
boolean increment;
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(rem == 0);
|
||||
// fall through
|
||||
case DOWN:
|
||||
increment = false;
|
||||
break;
|
||||
case UP:
|
||||
increment = true;
|
||||
break;
|
||||
case CEILING:
|
||||
increment = signum > 0;
|
||||
break;
|
||||
case FLOOR:
|
||||
increment = signum < 0;
|
||||
break;
|
||||
case HALF_EVEN:
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
int absRem = abs(rem);
|
||||
int cmpRemToHalfDivisor = absRem - (abs(q) - absRem);
|
||||
// subtracting two nonnegative ints can't overflow
|
||||
// cmpRemToHalfDivisor has the same sign as compare(abs(rem), abs(q) / 2).
|
||||
if (cmpRemToHalfDivisor == 0) { // exactly on the half mark
|
||||
increment = (mode == HALF_UP || (mode == HALF_EVEN & (div & 1) != 0));
|
||||
} else {
|
||||
increment = cmpRemToHalfDivisor > 0; // closer to the UP value
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return increment ? div + signum : div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code x mod m}, a non-negative value less than {@code m}. This
|
||||
* differs from {@code x % m}, which might be negative.
|
||||
*
|
||||
* <p>
|
||||
* For example:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
*
|
||||
* mod(7, 4) == 3
|
||||
* mod(-7, 4) == 1
|
||||
* mod(-1, 4) == 3
|
||||
* mod(-8, 4) == 0
|
||||
* mod(8, 4) == 0}
|
||||
* </pre>
|
||||
*
|
||||
* @throws ArithmeticException if {@code m <= 0}
|
||||
* @see <a href=
|
||||
* "http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3">
|
||||
* Remainder Operator</a>
|
||||
*/
|
||||
public static int mod(int x, int m) {
|
||||
if (m <= 0) {
|
||||
throw new ArithmeticException("Modulus " + m + " must be > 0");
|
||||
}
|
||||
int result = x % m;
|
||||
return (result >= 0) ? result : result + m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest common divisor of {@code a, b}. Returns {@code 0} if
|
||||
* {@code a == 0 && b == 0}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code a < 0} or {@code b < 0}
|
||||
*/
|
||||
public static int gcd(int a, int b) {
|
||||
/*
|
||||
* The reason we require both arguments to be >= 0 is because otherwise, what do
|
||||
* you return on gcd(0, Integer.MIN_VALUE)? BigInteger.gcd would return positive
|
||||
* 2^31, but positive 2^31 isn't an int.
|
||||
*/
|
||||
checkNonNegative("a", a);
|
||||
checkNonNegative("b", b);
|
||||
if (a == 0) {
|
||||
// 0 % b == 0, so b divides a, but the converse doesn't hold.
|
||||
// BigInteger.gcd is consistent with this decision.
|
||||
return b;
|
||||
} else if (b == 0) {
|
||||
return a; // similar logic
|
||||
}
|
||||
/*
|
||||
* Uses the binary GCD algorithm; see
|
||||
* http://en.wikipedia.org/wiki/Binary_GCD_algorithm. This is >40% faster than
|
||||
* the Euclidean algorithm in benchmarks.
|
||||
*/
|
||||
int aTwos = Integer.numberOfTrailingZeros(a);
|
||||
a >>= aTwos; // divide out all 2s
|
||||
int bTwos = Integer.numberOfTrailingZeros(b);
|
||||
b >>= bTwos; // divide out all 2s
|
||||
while (a != b) { // both a, b are odd
|
||||
// The key to the binary GCD algorithm is as follows:
|
||||
// Both a and b are odd. Assume a > b; then gcd(a - b, b) = gcd(a, b).
|
||||
// But in gcd(a - b, b), a - b is even and b is odd, so we can divide out powers
|
||||
// of two.
|
||||
|
||||
// We bend over backwards to avoid branching, adapting a technique from
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
|
||||
|
||||
int delta = a - b; // can't overflow, since a and b are nonnegative
|
||||
|
||||
int minDeltaOrZero = delta & (delta >> (Integer.SIZE - 1));
|
||||
// equivalent to Math.min(delta, 0)
|
||||
|
||||
a = delta - minDeltaOrZero - minDeltaOrZero; // sets a to Math.abs(a - b)
|
||||
// a is now nonnegative and even
|
||||
|
||||
b += minDeltaOrZero; // sets b to min(old a, b)
|
||||
a >>= Integer.numberOfTrailingZeros(a); // divide out all 2s, since 2 doesn't divide b
|
||||
}
|
||||
return a << min(aTwos, bTwos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of {@code a} and {@code b}, provided it does not overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code a + b} overflows in signed {@code int}
|
||||
* arithmetic
|
||||
*/
|
||||
public static int checkedAdd(int a, int b) {
|
||||
long result = (long) a + b;
|
||||
checkNoOverflow(result == (int) result);
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of {@code a} and {@code b}, provided it does not
|
||||
* overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code a - b} overflows in signed {@code int}
|
||||
* arithmetic
|
||||
*/
|
||||
public static int checkedSubtract(int a, int b) {
|
||||
long result = (long) a - b;
|
||||
checkNoOverflow(result == (int) result);
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of {@code a} and {@code b}, provided it does not
|
||||
* overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code a * b} overflows in signed {@code int}
|
||||
* arithmetic
|
||||
*/
|
||||
public static int checkedMultiply(int a, int b) {
|
||||
long result = (long) a * b;
|
||||
checkNoOverflow(result == (int) result);
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code b} to the {@code k}th power, provided it does not
|
||||
* overflow.
|
||||
*
|
||||
* <p>
|
||||
* {@link #pow} may be faster, but does not check for overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code b} to the {@code k}th power overflows
|
||||
* in signed {@code int} arithmetic
|
||||
*/
|
||||
public static int checkedPow(int b, int k) {
|
||||
checkNonNegative("exponent", k);
|
||||
switch (b) {
|
||||
case 0:
|
||||
return (k == 0) ? 1 : 0;
|
||||
case 1:
|
||||
return 1;
|
||||
case (-1):
|
||||
return ((k & 1) == 0) ? 1 : -1;
|
||||
case 2:
|
||||
checkNoOverflow(k < Integer.SIZE - 1);
|
||||
return 1 << k;
|
||||
case (-2):
|
||||
checkNoOverflow(k < Integer.SIZE);
|
||||
return ((k & 1) == 0) ? 1 << k : -1 << k;
|
||||
default:
|
||||
// continue below to handle the general case
|
||||
}
|
||||
int accum = 1;
|
||||
while (true) {
|
||||
switch (k) {
|
||||
case 0:
|
||||
return accum;
|
||||
case 1:
|
||||
return checkedMultiply(accum, b);
|
||||
default:
|
||||
if ((k & 1) != 0) {
|
||||
accum = checkedMultiply(accum, b);
|
||||
}
|
||||
k >>= 1;
|
||||
if (k > 0) {
|
||||
checkNoOverflow(-FLOOR_SQRT_MAX_INT <= b & b <= FLOOR_SQRT_MAX_INT);
|
||||
b *= b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static final int FLOOR_SQRT_MAX_INT = 46340;
|
||||
|
||||
/**
|
||||
* Returns {@code n!}, that is, the product of the first {@code n} positive
|
||||
* integers, {@code 1} if {@code n == 0}, or {@link Integer#MAX_VALUE} if the
|
||||
* result does not fit in a {@code int}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}
|
||||
*/
|
||||
public static int factorial(int n) {
|
||||
checkNonNegative("n", n);
|
||||
return (n < factorials.length) ? factorials[n] : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
private static final int[] factorials = { 1, 1, 1 * 2, 1 * 2 * 3, 1 * 2 * 3 * 4, 1 * 2 * 3 * 4 * 5,
|
||||
1 * 2 * 3 * 4 * 5 * 6, 1 * 2 * 3 * 4 * 5 * 6 * 7, 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8,
|
||||
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9, 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10,
|
||||
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11, 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 };
|
||||
|
||||
/**
|
||||
* Returns {@code n} choose {@code k}, also known as the binomial coefficient of
|
||||
* {@code n} and {@code k}, or {@link Integer#MAX_VALUE} if the result does not
|
||||
* fit in an {@code int}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}, {@code k < 0} or
|
||||
* {@code k > n}
|
||||
*/
|
||||
@GwtIncompatible("need BigIntegerMath to adequately test")
|
||||
public static int binomial(int n, int k) {
|
||||
checkNonNegative("n", n);
|
||||
checkNonNegative("k", k);
|
||||
checkArgument(k <= n, "k (%s) > n (%s)", k, n);
|
||||
if (k > (n >> 1)) {
|
||||
k = n - k;
|
||||
}
|
||||
if (k >= biggestBinomials.length || n > biggestBinomials[k]) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
switch (k) {
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return n;
|
||||
default:
|
||||
long result = 1;
|
||||
for (int i = 0; i < k; i++) {
|
||||
result *= n - i;
|
||||
result /= i + 1;
|
||||
}
|
||||
return (int) result;
|
||||
}
|
||||
}
|
||||
|
||||
// binomial(biggestBinomials[k], k) fits in an int, but not
|
||||
// binomial(biggestBinomials[k]+1,k).
|
||||
@VisibleForTesting
|
||||
static int[] biggestBinomials = { Integer.MAX_VALUE, Integer.MAX_VALUE, 65536, 2345, 477, 193, 110, 75, 58, 49, 43,
|
||||
39, 37, 35, 34, 34, 33 };
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of {@code x} and {@code y}, rounded towards
|
||||
* negative infinity. This method is overflow resilient.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public static int mean(int x, int y) {
|
||||
// Efficient method for computing the arithmetic mean.
|
||||
// The alternative (x + y) / 2 fails for large values.
|
||||
// The alternative (x + y) >>> 1 fails for negative values.
|
||||
return (x & y) + ((x ^ y) >> 1);
|
||||
}
|
||||
|
||||
private IntMath() {
|
||||
}
|
||||
}
|
755
sources/main/java/com/google/common/math/LongMath.java
Normal file
755
sources/main/java/com/google/common/math/LongMath.java
Normal file
@ -0,0 +1,755 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.math.MathPreconditions.checkNoOverflow;
|
||||
import static com.google.common.math.MathPreconditions.checkNonNegative;
|
||||
import static com.google.common.math.MathPreconditions.checkPositive;
|
||||
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.min;
|
||||
import static java.math.RoundingMode.HALF_EVEN;
|
||||
import static java.math.RoundingMode.HALF_UP;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* A class for arithmetic on values of type {@code long}. Where possible,
|
||||
* methods are defined and named analogously to their {@code BigInteger}
|
||||
* counterparts.
|
||||
*
|
||||
* <p>
|
||||
* The implementations of many methods in this class are based on material from
|
||||
* Henry S. Warren, Jr.'s <i>Hacker's Delight</i>, (Addison Wesley, 2002).
|
||||
*
|
||||
* <p>
|
||||
* Similar functionality for {@code int} and for {@link BigInteger} can be found
|
||||
* in {@link IntMath} and {@link BigIntegerMath} respectively. For other common
|
||||
* operations on {@code long} values, see
|
||||
* {@link com.google.common.primitives.Longs}.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 11.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class LongMath {
|
||||
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, |
|
||||
// instead of &&, ||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code x} represents a power of two.
|
||||
*
|
||||
* <p>
|
||||
* This differs from {@code Long.bitCount(x) == 1}, because
|
||||
* {@code Long.bitCount(Long.MIN_VALUE) == 1}, but {@link Long#MIN_VALUE} is not
|
||||
* a power of two.
|
||||
*/
|
||||
public static boolean isPowerOfTwo(long x) {
|
||||
return x > 0 & (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 1 if {@code x < y} as unsigned longs, and 0 otherwise. Assumes that x
|
||||
* - y fits into a signed long. The implementation is branch-free, and
|
||||
* benchmarks suggest it is measurably faster than the straightforward ternary
|
||||
* expression.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static int lessThanBranchFree(long x, long y) {
|
||||
// Returns the sign bit of x - y.
|
||||
return (int) (~~(x - y) >>> (Long.SIZE - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base-2 logarithm of {@code x}, rounded according to the specified
|
||||
* rounding mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code x} is not a power of two
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
// TODO(kevinb): remove after this warning is disabled globally
|
||||
public static int log2(long x, RoundingMode mode) {
|
||||
checkPositive("x", x);
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(isPowerOfTwo(x));
|
||||
// fall through
|
||||
case DOWN:
|
||||
case FLOOR:
|
||||
return (Long.SIZE - 1) - Long.numberOfLeadingZeros(x);
|
||||
|
||||
case UP:
|
||||
case CEILING:
|
||||
return Long.SIZE - Long.numberOfLeadingZeros(x - 1);
|
||||
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
// Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5
|
||||
int leadingZeros = Long.numberOfLeadingZeros(x);
|
||||
long cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros;
|
||||
// floor(2^(logFloor + 0.5))
|
||||
int logFloor = (Long.SIZE - 1) - leadingZeros;
|
||||
return logFloor + lessThanBranchFree(cmp, x);
|
||||
|
||||
default:
|
||||
throw new AssertionError("impossible");
|
||||
}
|
||||
}
|
||||
|
||||
/** The biggest half power of two that fits into an unsigned long */
|
||||
@VisibleForTesting
|
||||
static final long MAX_POWER_OF_SQRT2_UNSIGNED = 0xB504F333F9DE6484L;
|
||||
|
||||
/**
|
||||
* Returns the base-10 logarithm of {@code x}, rounded according to the
|
||||
* specified rounding mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x <= 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code x} is not a power of ten
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
@SuppressWarnings("fallthrough")
|
||||
// TODO(kevinb): remove after this warning is disabled globally
|
||||
public static int log10(long x, RoundingMode mode) {
|
||||
checkPositive("x", x);
|
||||
int logFloor = log10Floor(x);
|
||||
long floorPow = powersOf10[logFloor];
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(x == floorPow);
|
||||
// fall through
|
||||
case FLOOR:
|
||||
case DOWN:
|
||||
return logFloor;
|
||||
case CEILING:
|
||||
case UP:
|
||||
return logFloor + lessThanBranchFree(floorPow, x);
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
// sqrt(10) is irrational, so log10(x)-logFloor is never exactly 0.5
|
||||
return logFloor + lessThanBranchFree(halfPowersOf10[logFloor], x);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@GwtIncompatible("TODO")
|
||||
static int log10Floor(long x) {
|
||||
/*
|
||||
* Based on Hacker's Delight Fig. 11-5, the two-table-lookup, branch-free
|
||||
* implementation.
|
||||
*
|
||||
* The key idea is that based on the number of leading zeros (equivalently,
|
||||
* floor(log2(x))), we can narrow the possible floor(log10(x)) values to two.
|
||||
* For example, if floor(log2(x)) is 6, then 64 <= x < 128, so floor(log10(x))
|
||||
* is either 1 or 2.
|
||||
*/
|
||||
int y = maxLog10ForLeadingZeros[Long.numberOfLeadingZeros(x)];
|
||||
/*
|
||||
* y is the higher of the two possible values of floor(log10(x)). If x < 10^y,
|
||||
* then we want the lower of the two possible values, or y - 1, otherwise, we
|
||||
* want y.
|
||||
*/
|
||||
return y - lessThanBranchFree(x, powersOf10[y]);
|
||||
}
|
||||
|
||||
// maxLog10ForLeadingZeros[i] == floor(log10(2^(Long.SIZE - i)))
|
||||
@VisibleForTesting
|
||||
static final byte[] maxLog10ForLeadingZeros = { 19, 18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15, 14, 14,
|
||||
14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
|
||||
4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0 };
|
||||
|
||||
@GwtIncompatible("TODO")
|
||||
@VisibleForTesting
|
||||
static final long[] powersOf10 = { 1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L,
|
||||
1000000000L, 10000000000L, 100000000000L, 1000000000000L, 10000000000000L, 100000000000000L,
|
||||
1000000000000000L, 10000000000000000L, 100000000000000000L, 1000000000000000000L };
|
||||
|
||||
// halfPowersOf10[i] = largest long less than 10^(i + 0.5)
|
||||
@GwtIncompatible("TODO")
|
||||
@VisibleForTesting
|
||||
static final long[] halfPowersOf10 = { 3L, 31L, 316L, 3162L, 31622L, 316227L, 3162277L, 31622776L, 316227766L,
|
||||
3162277660L, 31622776601L, 316227766016L, 3162277660168L, 31622776601683L, 316227766016837L,
|
||||
3162277660168379L, 31622776601683793L, 316227766016837933L, 3162277660168379331L };
|
||||
|
||||
/**
|
||||
* Returns {@code b} to the {@code k}th power. Even if the result overflows, it
|
||||
* will be equal to {@code BigInteger.valueOf(b).pow(k).longValue()}. This
|
||||
* implementation runs in {@code O(log k)} time.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code k < 0}
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long pow(long b, int k) {
|
||||
checkNonNegative("exponent", k);
|
||||
if (-2 <= b && b <= 2) {
|
||||
switch ((int) b) {
|
||||
case 0:
|
||||
return (k == 0) ? 1 : 0;
|
||||
case 1:
|
||||
return 1;
|
||||
case (-1):
|
||||
return ((k & 1) == 0) ? 1 : -1;
|
||||
case 2:
|
||||
return (k < Long.SIZE) ? 1L << k : 0;
|
||||
case (-2):
|
||||
if (k < Long.SIZE) {
|
||||
return ((k & 1) == 0) ? 1L << k : -(1L << k);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
for (long accum = 1;; k >>= 1) {
|
||||
switch (k) {
|
||||
case 0:
|
||||
return accum;
|
||||
case 1:
|
||||
return accum * b;
|
||||
default:
|
||||
accum *= ((k & 1) == 0) ? 1 : b;
|
||||
b *= b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of {@code x}, rounded with the specified rounding
|
||||
* mode.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code x < 0}
|
||||
* @throws ArithmeticException if {@code mode} is
|
||||
* {@link RoundingMode#UNNECESSARY} and
|
||||
* {@code sqrt(x)} is not an integer
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static long sqrt(long x, RoundingMode mode) {
|
||||
checkNonNegative("x", x);
|
||||
if (fitsInInt(x)) {
|
||||
return IntMath.sqrt((int) x, mode);
|
||||
}
|
||||
/*
|
||||
* Let k be the true value of floor(sqrt(x)), so that
|
||||
*
|
||||
* k * k <= x < (k + 1) * (k + 1) (double) (k * k) <= (double) x <= (double) ((k
|
||||
* + 1) * (k + 1)) since casting to double is nondecreasing. Note that the
|
||||
* right-hand inequality is no longer strict. Math.sqrt(k * k) <= Math.sqrt(x)
|
||||
* <= Math.sqrt((k + 1) * (k + 1)) since Math.sqrt is monotonic. (long)
|
||||
* Math.sqrt(k * k) <= (long) Math.sqrt(x) <= (long) Math.sqrt((k + 1) * (k +
|
||||
* 1)) since casting to long is monotonic k <= (long) Math.sqrt(x) <= k + 1
|
||||
* since (long) Math.sqrt(k * k) == k, as checked exhaustively in {@link
|
||||
* LongMathTest#testSqrtOfPerfectSquareAsDoubleIsPerfect}
|
||||
*/
|
||||
long guess = (long) Math.sqrt(x);
|
||||
// Note: guess is always <= FLOOR_SQRT_MAX_LONG.
|
||||
long guessSquared = guess * guess;
|
||||
// Note (2013-2-26): benchmarks indicate that, inscrutably enough, using if
|
||||
// statements is
|
||||
// faster here than using lessThanBranchFree.
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(guessSquared == x);
|
||||
return guess;
|
||||
case FLOOR:
|
||||
case DOWN:
|
||||
if (x < guessSquared) {
|
||||
return guess - 1;
|
||||
}
|
||||
return guess;
|
||||
case CEILING:
|
||||
case UP:
|
||||
if (x > guessSquared) {
|
||||
return guess + 1;
|
||||
}
|
||||
return guess;
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
case HALF_EVEN:
|
||||
long sqrtFloor = guess - ((x < guessSquared) ? 1 : 0);
|
||||
long halfSquare = sqrtFloor * sqrtFloor + sqrtFloor;
|
||||
/*
|
||||
* We wish to test whether or not x <= (sqrtFloor + 0.5)^2 = halfSquare + 0.25.
|
||||
* Since both x and halfSquare are integers, this is equivalent to testing
|
||||
* whether or not x <= halfSquare. (We have to deal with overflow, though.)
|
||||
*
|
||||
* If we treat halfSquare as an unsigned long, we know that sqrtFloor^2 <= x <
|
||||
* (sqrtFloor + 1)^2 halfSquare - sqrtFloor <= x < halfSquare + sqrtFloor + 1 so
|
||||
* |x - halfSquare| <= sqrtFloor. Therefore, it's safe to treat x - halfSquare
|
||||
* as a signed long, so lessThanBranchFree is safe for use.
|
||||
*/
|
||||
return sqrtFloor + lessThanBranchFree(halfSquare, x);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of dividing {@code p} by {@code q}, rounding using the
|
||||
* specified {@code RoundingMode}.
|
||||
*
|
||||
* @throws ArithmeticException if {@code q == 0}, or if
|
||||
* {@code mode == UNNECESSARY} and {@code a} is not
|
||||
* an integer multiple of {@code b}
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static long divide(long p, long q, RoundingMode mode) {
|
||||
checkNotNull(mode);
|
||||
long div = p / q; // throws if q == 0
|
||||
long rem = p - q * div; // equals p % q
|
||||
|
||||
if (rem == 0) {
|
||||
return div;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normal Java division rounds towards 0, consistently with RoundingMode.DOWN.
|
||||
* We just have to deal with the cases where rounding towards 0 is wrong, which
|
||||
* typically depends on the sign of p / q.
|
||||
*
|
||||
* signum is 1 if p and q are both nonnegative or both negative, and -1
|
||||
* otherwise.
|
||||
*/
|
||||
int signum = 1 | (int) ((p ^ q) >> (Long.SIZE - 1));
|
||||
boolean increment;
|
||||
switch (mode) {
|
||||
case UNNECESSARY:
|
||||
checkRoundingUnnecessary(rem == 0);
|
||||
// fall through
|
||||
case DOWN:
|
||||
increment = false;
|
||||
break;
|
||||
case UP:
|
||||
increment = true;
|
||||
break;
|
||||
case CEILING:
|
||||
increment = signum > 0;
|
||||
break;
|
||||
case FLOOR:
|
||||
increment = signum < 0;
|
||||
break;
|
||||
case HALF_EVEN:
|
||||
case HALF_DOWN:
|
||||
case HALF_UP:
|
||||
long absRem = abs(rem);
|
||||
long cmpRemToHalfDivisor = absRem - (abs(q) - absRem);
|
||||
// subtracting two nonnegative longs can't overflow
|
||||
// cmpRemToHalfDivisor has the same sign as compare(abs(rem), abs(q) / 2).
|
||||
if (cmpRemToHalfDivisor == 0) { // exactly on the half mark
|
||||
increment = (mode == HALF_UP | (mode == HALF_EVEN & (div & 1) != 0));
|
||||
} else {
|
||||
increment = cmpRemToHalfDivisor > 0; // closer to the UP value
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return increment ? div + signum : div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code x mod m}, a non-negative value less than {@code m}. This
|
||||
* differs from {@code x % m}, which might be negative.
|
||||
*
|
||||
* <p>
|
||||
* For example:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
*
|
||||
* mod(7, 4) == 3
|
||||
* mod(-7, 4) == 1
|
||||
* mod(-1, 4) == 3
|
||||
* mod(-8, 4) == 0
|
||||
* mod(8, 4) == 0}
|
||||
* </pre>
|
||||
*
|
||||
* @throws ArithmeticException if {@code m <= 0}
|
||||
* @see <a href=
|
||||
* "http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3">
|
||||
* Remainder Operator</a>
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static int mod(long x, int m) {
|
||||
// Cast is safe because the result is guaranteed in the range [0, m)
|
||||
return (int) mod(x, (long) m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code x mod m}, a non-negative value less than {@code m}. This
|
||||
* differs from {@code x % m}, which might be negative.
|
||||
*
|
||||
* <p>
|
||||
* For example:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
*
|
||||
* mod(7, 4) == 3
|
||||
* mod(-7, 4) == 1
|
||||
* mod(-1, 4) == 3
|
||||
* mod(-8, 4) == 0
|
||||
* mod(8, 4) == 0}
|
||||
* </pre>
|
||||
*
|
||||
* @throws ArithmeticException if {@code m <= 0}
|
||||
* @see <a href=
|
||||
* "http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3">
|
||||
* Remainder Operator</a>
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long mod(long x, long m) {
|
||||
if (m <= 0) {
|
||||
throw new ArithmeticException("Modulus must be positive");
|
||||
}
|
||||
long result = x % m;
|
||||
return (result >= 0) ? result : result + m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest common divisor of {@code a, b}. Returns {@code 0} if
|
||||
* {@code a == 0 && b == 0}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code a < 0} or {@code b < 0}
|
||||
*/
|
||||
public static long gcd(long a, long b) {
|
||||
/*
|
||||
* The reason we require both arguments to be >= 0 is because otherwise, what do
|
||||
* you return on gcd(0, Long.MIN_VALUE)? BigInteger.gcd would return positive
|
||||
* 2^63, but positive 2^63 isn't an int.
|
||||
*/
|
||||
checkNonNegative("a", a);
|
||||
checkNonNegative("b", b);
|
||||
if (a == 0) {
|
||||
// 0 % b == 0, so b divides a, but the converse doesn't hold.
|
||||
// BigInteger.gcd is consistent with this decision.
|
||||
return b;
|
||||
} else if (b == 0) {
|
||||
return a; // similar logic
|
||||
}
|
||||
/*
|
||||
* Uses the binary GCD algorithm; see
|
||||
* http://en.wikipedia.org/wiki/Binary_GCD_algorithm. This is >60% faster than
|
||||
* the Euclidean algorithm in benchmarks.
|
||||
*/
|
||||
int aTwos = Long.numberOfTrailingZeros(a);
|
||||
a >>= aTwos; // divide out all 2s
|
||||
int bTwos = Long.numberOfTrailingZeros(b);
|
||||
b >>= bTwos; // divide out all 2s
|
||||
while (a != b) { // both a, b are odd
|
||||
// The key to the binary GCD algorithm is as follows:
|
||||
// Both a and b are odd. Assume a > b; then gcd(a - b, b) = gcd(a, b).
|
||||
// But in gcd(a - b, b), a - b is even and b is odd, so we can divide out powers
|
||||
// of two.
|
||||
|
||||
// We bend over backwards to avoid branching, adapting a technique from
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
|
||||
|
||||
long delta = a - b; // can't overflow, since a and b are nonnegative
|
||||
|
||||
long minDeltaOrZero = delta & (delta >> (Long.SIZE - 1));
|
||||
// equivalent to Math.min(delta, 0)
|
||||
|
||||
a = delta - minDeltaOrZero - minDeltaOrZero; // sets a to Math.abs(a - b)
|
||||
// a is now nonnegative and even
|
||||
|
||||
b += minDeltaOrZero; // sets b to min(old a, b)
|
||||
a >>= Long.numberOfTrailingZeros(a); // divide out all 2s, since 2 doesn't divide b
|
||||
}
|
||||
return a << min(aTwos, bTwos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of {@code a} and {@code b}, provided it does not overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code a + b} overflows in signed {@code long}
|
||||
* arithmetic
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long checkedAdd(long a, long b) {
|
||||
long result = a + b;
|
||||
checkNoOverflow((a ^ b) < 0 | (a ^ result) >= 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of {@code a} and {@code b}, provided it does not
|
||||
* overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code a - b} overflows in signed {@code long}
|
||||
* arithmetic
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long checkedSubtract(long a, long b) {
|
||||
long result = a - b;
|
||||
checkNoOverflow((a ^ b) >= 0 | (a ^ result) >= 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of {@code a} and {@code b}, provided it does not
|
||||
* overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code a * b} overflows in signed {@code long}
|
||||
* arithmetic
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long checkedMultiply(long a, long b) {
|
||||
// Hacker's Delight, Section 2-12
|
||||
int leadingZeros = Long.numberOfLeadingZeros(a) + Long.numberOfLeadingZeros(~a) + Long.numberOfLeadingZeros(b)
|
||||
+ Long.numberOfLeadingZeros(~b);
|
||||
/*
|
||||
* If leadingZeros > Long.SIZE + 1 it's definitely fine, if it's < Long.SIZE
|
||||
* it's definitely bad. We do the leadingZeros check to avoid the division below
|
||||
* if at all possible.
|
||||
*
|
||||
* Otherwise, if b == Long.MIN_VALUE, then the only allowed values of a are 0
|
||||
* and 1. We take care of all a < 0 with their own check, because in particular,
|
||||
* the case a == -1 will incorrectly pass the division check below.
|
||||
*
|
||||
* In all other cases, we check that either a is 0 or the result is consistent
|
||||
* with division.
|
||||
*/
|
||||
if (leadingZeros > Long.SIZE + 1) {
|
||||
return a * b;
|
||||
}
|
||||
checkNoOverflow(leadingZeros >= Long.SIZE);
|
||||
checkNoOverflow(a >= 0 | b != Long.MIN_VALUE);
|
||||
long result = a * b;
|
||||
checkNoOverflow(a == 0 || result / a == b);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code b} to the {@code k}th power, provided it does not
|
||||
* overflow.
|
||||
*
|
||||
* @throws ArithmeticException if {@code b} to the {@code k}th power overflows
|
||||
* in signed {@code long} arithmetic
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long checkedPow(long b, int k) {
|
||||
checkNonNegative("exponent", k);
|
||||
if (b >= -2 & b <= 2) {
|
||||
switch ((int) b) {
|
||||
case 0:
|
||||
return (k == 0) ? 1 : 0;
|
||||
case 1:
|
||||
return 1;
|
||||
case (-1):
|
||||
return ((k & 1) == 0) ? 1 : -1;
|
||||
case 2:
|
||||
checkNoOverflow(k < Long.SIZE - 1);
|
||||
return 1L << k;
|
||||
case (-2):
|
||||
checkNoOverflow(k < Long.SIZE);
|
||||
return ((k & 1) == 0) ? (1L << k) : (-1L << k);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
long accum = 1;
|
||||
while (true) {
|
||||
switch (k) {
|
||||
case 0:
|
||||
return accum;
|
||||
case 1:
|
||||
return checkedMultiply(accum, b);
|
||||
default:
|
||||
if ((k & 1) != 0) {
|
||||
accum = checkedMultiply(accum, b);
|
||||
}
|
||||
k >>= 1;
|
||||
if (k > 0) {
|
||||
checkNoOverflow(b <= FLOOR_SQRT_MAX_LONG);
|
||||
b *= b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static final long FLOOR_SQRT_MAX_LONG = 3037000499L;
|
||||
|
||||
/**
|
||||
* Returns {@code n!}, that is, the product of the first {@code n} positive
|
||||
* integers, {@code 1} if {@code n == 0}, or {@link Long#MAX_VALUE} if the
|
||||
* result does not fit in a {@code long}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}
|
||||
*/
|
||||
@GwtIncompatible("TODO")
|
||||
public static long factorial(int n) {
|
||||
checkNonNegative("n", n);
|
||||
return (n < factorials.length) ? factorials[n] : Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
static final long[] factorials = { 1L, 1L, 1L * 2, 1L * 2 * 3, 1L * 2 * 3 * 4, 1L * 2 * 3 * 4 * 5,
|
||||
1L * 2 * 3 * 4 * 5 * 6, 1L * 2 * 3 * 4 * 5 * 6 * 7, 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9, 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11, 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19,
|
||||
1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 };
|
||||
|
||||
/**
|
||||
* Returns {@code n} choose {@code k}, also known as the binomial coefficient of
|
||||
* {@code n} and {@code k}, or {@link Long#MAX_VALUE} if the result does not fit
|
||||
* in a {@code long}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code n < 0}, {@code k < 0}, or
|
||||
* {@code k > n}
|
||||
*/
|
||||
public static long binomial(int n, int k) {
|
||||
checkNonNegative("n", n);
|
||||
checkNonNegative("k", k);
|
||||
checkArgument(k <= n, "k (%s) > n (%s)", k, n);
|
||||
if (k > (n >> 1)) {
|
||||
k = n - k;
|
||||
}
|
||||
switch (k) {
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return n;
|
||||
default:
|
||||
if (n < factorials.length) {
|
||||
return factorials[n] / (factorials[k] * factorials[n - k]);
|
||||
} else if (k >= biggestBinomials.length || n > biggestBinomials[k]) {
|
||||
return Long.MAX_VALUE;
|
||||
} else if (k < biggestSimpleBinomials.length && n <= biggestSimpleBinomials[k]) {
|
||||
// guaranteed not to overflow
|
||||
long result = n--;
|
||||
for (int i = 2; i <= k; n--, i++) {
|
||||
result *= n;
|
||||
result /= i;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
int nBits = LongMath.log2(n, RoundingMode.CEILING);
|
||||
|
||||
long result = 1;
|
||||
long numerator = n--;
|
||||
long denominator = 1;
|
||||
|
||||
int numeratorBits = nBits;
|
||||
// This is an upper bound on log2(numerator, ceiling).
|
||||
|
||||
/*
|
||||
* We want to do this in long math for speed, but want to avoid overflow. We
|
||||
* adapt the technique previously used by BigIntegerMath: maintain separate
|
||||
* numerator and denominator accumulators, multiplying the fraction into result
|
||||
* when near overflow.
|
||||
*/
|
||||
for (int i = 2; i <= k; i++, n--) {
|
||||
if (numeratorBits + nBits < Long.SIZE - 1) {
|
||||
// It's definitely safe to multiply into numerator and denominator.
|
||||
numerator *= n;
|
||||
denominator *= i;
|
||||
numeratorBits += nBits;
|
||||
} else {
|
||||
// It might not be safe to multiply into numerator and denominator,
|
||||
// so multiply (numerator / denominator) into result.
|
||||
result = multiplyFraction(result, numerator, denominator);
|
||||
numerator = n;
|
||||
denominator = i;
|
||||
numeratorBits = nBits;
|
||||
}
|
||||
}
|
||||
return multiplyFraction(result, numerator, denominator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns (x * numerator / denominator), which is assumed to come out to an
|
||||
* integral value.
|
||||
*/
|
||||
static long multiplyFraction(long x, long numerator, long denominator) {
|
||||
if (x == 1) {
|
||||
return numerator / denominator;
|
||||
}
|
||||
long commonDivisor = gcd(x, denominator);
|
||||
x /= commonDivisor;
|
||||
denominator /= commonDivisor;
|
||||
// We know gcd(x, denominator) = 1, and x * numerator / denominator is exact,
|
||||
// so denominator must be a divisor of numerator.
|
||||
return x * (numerator / denominator);
|
||||
}
|
||||
|
||||
/*
|
||||
* binomial(biggestBinomials[k], k) fits in a long, but not
|
||||
* binomial(biggestBinomials[k] + 1, k).
|
||||
*/
|
||||
static final int[] biggestBinomials = { Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 3810779, 121977,
|
||||
16175, 4337, 1733, 887, 534, 361, 265, 206, 169, 143, 125, 111, 101, 94, 88, 83, 79, 76, 74, 72, 70, 69, 68,
|
||||
67, 67, 66, 66, 66, 66 };
|
||||
|
||||
/*
|
||||
* binomial(biggestSimpleBinomials[k], k) doesn't need to use the slower
|
||||
* GCD-based impl, but binomial(biggestSimpleBinomials[k] + 1, k) does.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static final int[] biggestSimpleBinomials = { Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 2642246,
|
||||
86251, 11724, 3218, 1313, 684, 419, 287, 214, 169, 139, 119, 105, 95, 87, 81, 76, 73, 70, 68, 66, 64, 63,
|
||||
62, 62, 61, 61, 61 };
|
||||
// These values were generated by using checkedMultiply to see when the simple
|
||||
// multiply/divide
|
||||
// algorithm would lead to an overflow.
|
||||
|
||||
static boolean fitsInInt(long x) {
|
||||
return (int) x == x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of {@code x} and {@code y}, rounded toward
|
||||
* negative infinity. This method is resilient to overflow.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public static long mean(long x, long y) {
|
||||
// Efficient method for computing the arithmetic mean.
|
||||
// The alternative (x + y) / 2 fails for large values.
|
||||
// The alternative (x + y) >>> 1 fails for negative values.
|
||||
return (x & y) + ((x ^ y) >> 1);
|
||||
}
|
||||
|
||||
private LongMath() {
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.math;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* A collection of preconditions for math functions.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
*/
|
||||
@GwtCompatible
|
||||
final class MathPreconditions {
|
||||
static int checkPositive(@Nullable String role, int x) {
|
||||
if (x <= 0) {
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be > 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static long checkPositive(@Nullable String role, long x) {
|
||||
if (x <= 0) {
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be > 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static BigInteger checkPositive(@Nullable String role, BigInteger x) {
|
||||
if (x.signum() <= 0) {
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be > 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static int checkNonNegative(@Nullable String role, int x) {
|
||||
if (x < 0) {
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static long checkNonNegative(@Nullable String role, long x) {
|
||||
if (x < 0) {
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static BigInteger checkNonNegative(@Nullable String role, BigInteger x) {
|
||||
if (x.signum() < 0) {
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static double checkNonNegative(@Nullable String role, double x) {
|
||||
if (!(x >= 0)) { // not x < 0, to work with NaN.
|
||||
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static void checkRoundingUnnecessary(boolean condition) {
|
||||
if (!condition) {
|
||||
throw new ArithmeticException("mode was UNNECESSARY, but rounding was necessary");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkInRange(boolean condition) {
|
||||
if (!condition) {
|
||||
throw new ArithmeticException("not in range");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkNoOverflow(boolean condition) {
|
||||
if (!condition) {
|
||||
throw new ArithmeticException("overflow");
|
||||
}
|
||||
}
|
||||
|
||||
private MathPreconditions() {
|
||||
}
|
||||
}
|
33
sources/main/java/com/google/common/math/package-info.java
Normal file
33
sources/main/java/com/google/common/math/package-info.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Arithmetic functions operating on primitive values and
|
||||
* {@link java.math.BigInteger} instances.
|
||||
*
|
||||
* <p>
|
||||
* This package is a part of the open-source
|
||||
* <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/MathExplained"> math
|
||||
* utilities</a>.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
package com.google.common.math;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
Reference in New Issue
Block a user