Refine search
/** * 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 // DoubleMath.isMathematicalInteger public void testIsMathematicalIntegerNotFinite() { for (double d : Arrays.asList(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) { assertFalse(DoubleMath.isMathematicalInteger(d)); } }
@GwtIncompatible // DoubleMath.roundToLong(double, RoundingMode) public void testRoundNaNToLongAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { DoubleMath.roundToLong(Double.NaN, mode); fail("Expected ArithmeticException"); } catch (ArithmeticException expected) { } } }
@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; switch (mode) { case UNNECESSARY: checkRoundingUnnecessary(isPowerOfTwo(x)); 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);
private static void runTestFuzzyCompare(int toleranceIndex) { double tolerance = get(TOLERANCE_CANDIDATES, toleranceIndex); for (double a : ALL_DOUBLE_CANDIDATES) { for (double b : ALL_DOUBLE_CANDIDATES) { int expected = DoubleMath.fuzzyEquals(a, b, tolerance) ? 0 : Double.compare(a, b); int actual = DoubleMath.fuzzyCompare(a, b, tolerance); assertEquals(Integer.signum(expected), Integer.signum(actual)); } } }
@GwtIncompatible // DoubleMath.isPowerOfTwo, DoubleMath.log2(double, RoundingMode), StrictMath public void testIsPowerOfTwo() { for (double x : ALL_DOUBLE_CANDIDATES) { boolean expected = x > 0 && !Double.isInfinite(x) && !Double.isNaN(x) && StrictMath.pow(2.0, DoubleMath.log2(x, FLOOR)) == x; assertEquals(expected, DoubleMath.isPowerOfTwo(x)); } }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of * {@code values}. * * <p>If these values are a sample drawn from a population, this is also an unbiased estimator of * the arithmetic mean of the population. * * @param values a nonempty series of values, which will be converted to {@code double} values * (this may cause loss of precision) * @throws IllegalArgumentException if {@code values} is empty or contains any non-finite value * @deprecated Use {@link Stats#meanOf} instead, noting the less strict handling of non-finite * values. */ @Deprecated // com.google.common.math.DoubleUtils @GwtIncompatible public static double mean(Iterable<? extends Number> values) { return mean(values.iterator()); }
/** * 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; }
@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"); checkRoundingUnnecessary(isMathematicalInteger(x)); return x; if (x >= 0.0 || isMathematicalInteger(x)) { return x; } else { if (x <= 0.0 || isMathematicalInteger(x)) { return x; } else { if (isMathematicalInteger(x)) { return x; } else {
@GwtIncompatible // TODO private static BigInteger sqrtApproxWithDoubles(BigInteger x) { return DoubleMath.roundToBigInteger(Math.sqrt(DoubleUtils.bigToDouble(x)), HALF_EVEN); }
@GwtIncompatible // DoubleMath.log2(double, RoundingMode) public void testRoundLog2ThrowsOnNegative() { for (RoundingMode mode : ALL_ROUNDING_MODES) { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { try { DoubleMath.log2(-d, mode); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } } } }
@GwtIncompatible // DoubleMath.roundToInt(double, RoundingMode) public void testRoundNaNToIntAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { DoubleMath.roundToInt(Double.NaN, mode); fail("Expected ArithmeticException"); } catch (ArithmeticException expected) { } } }
@GwtIncompatible // DoubleMath.roundToBigInteger(double, RoundingMode) public void testRoundFractionalDoubleToBigInteger() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { BigDecimal expected = new BigDecimal(d).setScale(0, mode); assertEquals(expected.toBigInteger(), DoubleMath.roundToBigInteger(d, mode)); } } }
/** * 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> */ // #roundIntermediate, java.lang.Math.getExponent, com.google.common.math.DoubleUtils @GwtIncompatible 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 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); checkInRangeForRoundingInputs( z > MIN_INT_AS_DOUBLE - 1.0 & z < MAX_INT_AS_DOUBLE + 1.0, x, mode); return (int) z; }
@GwtIncompatible // DoubleMath.isPowerOfTwo, DoubleMath.log2(double, RoundingMode), StrictMath public void testIsPowerOfTwoYes() { for (int i = -1074; i <= 1023; i++) { assertTrue(DoubleMath.isPowerOfTwo(StrictMath.pow(2.0, i))); } }
private static long saturatedFloorCastToLong(double value, long minValue, double minValueAsDouble, long maxValue, double maxValuePlusOneAsDouble) { if (value <= minValueAsDouble) { return minValue; } if (value + 1 >= maxValuePlusOneAsDouble) { return maxValue; } return DoubleMath.roundToLong(value, FLOOR); }
@Nonnull public static String formatValue(@Nonnull Object value) { if (value instanceof Double) { Double doubleValue = (Double) value; // String.format is very expensive, so avoid it for whole numbers that can fit in Long. // We simply append ".00000" to long, in order to keep the existing behavior. if (doubleValue <= Long.MAX_VALUE && DoubleMath.isMathematicalInteger(doubleValue)) { return Long.toString(doubleValue.longValue()) + ".00000"; } else { return String.format(Locale.US, "%1.5f", doubleValue); } } else { return value.toString(); } }
/** * Compute the target partition size. */ private int computeTargetPartitionSize(Histogram histogram, int minTargetPartitionSize, int maxPartitions) { return Math.max(minTargetPartitionSize, DoubleMath.roundToInt((double) histogram.totalRecordCount / maxPartitions, RoundingMode.CEILING)); }