11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.math;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.IMPLICIT_BIT;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.SIGNIFICAND_BITS;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.getExponent;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.getSignificand;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.isFinite;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.isNormal;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.next;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.DoubleUtils.scaleNormalize;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathPreconditions.checkInRange;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathPreconditions.checkNonNegative;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.BigInteger;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.RoundingMode;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.VisibleForTesting;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A class for arithmetic on doubles that is not covered by {@link java.lang.Math}.
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class DoubleMath {
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * This method returns a value y such that rounding y DOWN (towards zero) gives the same result
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * as rounding x according to the specified mode.
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static double roundIntermediate(double x, RoundingMode mode) {
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!isFinite(x)) {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new ArithmeticException("input is infinite or NaN");
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    switch (mode) {
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case UNNECESSARY:
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkRoundingUnnecessary(isMathematicalInteger(x));
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return x;
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case FLOOR:
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (x >= 0.0) ? x : Math.floor(x);
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case CEILING:
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (x >= 0.0) ? Math.ceil(x) : x;
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case DOWN:
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return x;
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case UP:
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (x >= 0.0) ? Math.ceil(x) : Math.floor(x);
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case HALF_EVEN:
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Math.rint(x);
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case HALF_UP:
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (isMathematicalInteger(x)) {
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return x;
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } else {
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return (x >= 0.0) ? x + 0.5 : x - 0.5;
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case HALF_DOWN:
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (isMathematicalInteger(x)) {
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return x;
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } else if (x >= 0.0) {
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          double z = x + 0.5;
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return (z == x) ? x : next(z, false); // x + 0.5 - epsilon
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } else {
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          double z = x - 0.5;
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return (z == x) ? x : next(z, true); // x - 0.5 + epsilon
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      default:
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throw new AssertionError();
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the {@code int} value that is equal to {@code x} rounded with the specified rounding
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * mode, if possible.
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws ArithmeticException if
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <ul>
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x} is infinite or NaN
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x}, after being rounded to a mathematical integer using the specified
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         rounding mode, is either less than {@code Integer.MIN_VALUE} or greater than {@code
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         Integer.MAX_VALUE}
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x} is not a mathematical integer and {@code mode} is
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         {@link RoundingMode#UNNECESSARY}
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         </ul>
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static int roundToInt(double x, RoundingMode mode) {
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    double z = roundIntermediate(x, mode);
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkInRange(z > MIN_INT_AS_DOUBLE - 1.0 & z < MAX_INT_AS_DOUBLE + 1.0);
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (int) z;
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final double MIN_INT_AS_DOUBLE = -0x1p31;
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final double MAX_INT_AS_DOUBLE = 0x1p31 - 1.0;
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the {@code long} value that is equal to {@code x} rounded with the specified rounding
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * mode, if possible.
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws ArithmeticException if
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <ul>
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x} is infinite or NaN
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x}, after being rounded to a mathematical integer using the specified
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         rounding mode, is either less than {@code Long.MIN_VALUE} or greater than {@code
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         Long.MAX_VALUE}
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x} is not a mathematical integer and {@code mode} is
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         {@link RoundingMode#UNNECESSARY}
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         </ul>
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static long roundToLong(double x, RoundingMode mode) {
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    double z = roundIntermediate(x, mode);
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkInRange(MIN_LONG_AS_DOUBLE - z < 1.0 & z < MAX_LONG_AS_DOUBLE_PLUS_ONE);
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (long) z;
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final double MIN_LONG_AS_DOUBLE = -0x1p63;
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * We cannot store Long.MAX_VALUE as a double without losing precision.  Instead, we store
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Long.MAX_VALUE + 1 == -Long.MIN_VALUE, and then offset all comparisons by 1.
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final double MAX_LONG_AS_DOUBLE_PLUS_ONE = 0x1p63;
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the {@code BigInteger} value that is equal to {@code x} rounded with the specified
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * rounding mode, if possible.
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws ArithmeticException if
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <ul>
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x} is infinite or NaN
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         <li>{@code x} is not a mathematical integer and {@code mode} is
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         {@link RoundingMode#UNNECESSARY}
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         </ul>
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static BigInteger roundToBigInteger(double x, RoundingMode mode) {
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    x = roundIntermediate(x, mode);
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (MIN_LONG_AS_DOUBLE - x < 1.0 & x < MAX_LONG_AS_DOUBLE_PLUS_ONE) {
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return BigInteger.valueOf((long) x);
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int exponent = getExponent(x);
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (exponent < 0) {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return BigInteger.ZERO;
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long significand = getSignificand(x);
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BigInteger result = BigInteger.valueOf(significand).shiftLeft(exponent - SIGNIFICAND_BITS);
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (x < 0) ? result.negate() : result;
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns {@code true} if {@code x} is exactly equal to {@code 2^k} for some finite integer
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code k}.
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static boolean isPowerOfTwo(double x) {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return x > 0.0 && isFinite(x) && LongMath.isPowerOfTwo(getSignificand(x));
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the base 2 logarithm of a double value.
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Special cases:
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <ul>
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>If {@code x} is NaN or less than zero, the result is NaN.
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>If {@code x} is positive infinity, the result is positive infinity.
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>If {@code x} is positive or negative zero, the result is negative infinity.
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * </ul>
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The computed result must be within 1 ulp of the exact result.
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>If the result of this method will be immediately rounded to an {@code int},
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #log2(double, RoundingMode)} is faster.
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static double log2(double x) {
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Math.log(x) / LN_2; // surprisingly within 1 ulp according to tests
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final double LN_2 = Math.log(2);
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the base 2 logarithm of a double value, rounded with the specified rounding mode to an
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code int}.
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Regardless of the rounding mode, this is faster than {@code (int) log2(x)}.
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code x <= 0.0}, {@code x} is NaN, or {@code x} is
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         infinite
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("fallthrough")
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static int log2(double x, RoundingMode mode) {
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkArgument(x > 0.0 && isFinite(x), "x must be positive and finite");
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int exponent = getExponent(x);
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!isNormal(x)) {
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return log2(x * IMPLICIT_BIT, mode) - SIGNIFICAND_BITS;
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Do the calculation on a normal value.
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // x is positive, finite, and normal
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean increment;
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    switch (mode) {
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case UNNECESSARY:
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkRoundingUnnecessary(isPowerOfTwo(x));
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // fall through
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case FLOOR:
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        increment = false;
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        break;
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case CEILING:
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        increment = !isPowerOfTwo(x);
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        break;
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case DOWN:
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        increment = exponent < 0 & !isPowerOfTwo(x);
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        break;
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case UP:
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        increment = exponent >= 0 & !isPowerOfTwo(x);
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        break;
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case HALF_DOWN:
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case HALF_EVEN:
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      case HALF_UP:
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        double xScaled = scaleNormalize(x);
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // sqrt(2) is irrational, and the spec is relative to the "exact numerical result,"
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // so log2(x) is never exactly exponent + 0.5.
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        increment = (xScaled * xScaled) > 2.0;
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        break;
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      default:
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throw new AssertionError();
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return increment ? exponent + 1 : exponent;
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns {@code true} if {@code x} represents a mathematical integer.
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>This is equivalent to, but not necessarily implemented as, the expression {@code
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * !Double.isNaN(x) && !Double.isInfinite(x) && x == Math.rint(x)}.
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static boolean isMathematicalInteger(double x) {
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return isFinite(x)
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        && (x == 0.0 || SIGNIFICAND_BITS
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            - Long.numberOfTrailingZeros(getSignificand(x)) <= getExponent(x));
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns {@code n!}, that is, the product of the first {@code n} positive
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * integers, {@code 1} if {@code n == 0}, or e n!}, or
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Double#POSITIVE_INFINITY} if {@code n! > Double.MAX_VALUE}.
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The result is within 1 ulp of the true value.
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code n < 0}
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static double factorial(int n) {
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNonNegative("n", n);
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (n > MAX_FACTORIAL) {
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Double.POSITIVE_INFINITY;
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else {
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Multiplying the last (n & 0xf) values into their own accumulator gives a more accurate
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // result than multiplying by EVERY_SIXTEENTH_FACTORIAL[n >> 4] directly.
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      double accum = 1.0;
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int i = 1 + (n & ~0xf); i <= n; i++) {
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        accum *= i;
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return accum * EVERY_SIXTEENTH_FACTORIAL[n >> 4];
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @VisibleForTesting
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final int MAX_FACTORIAL = 170;
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @VisibleForTesting
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final double[] EVERY_SIXTEENTH_FACTORIAL = {
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.0p0,
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.30777758p44,
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.956ad0aae33a4p117,
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.ee69a78d72cb6p202,
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.fe478ee34844ap295,
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.c619094edabffp394,
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.3638dd7bd6347p498,
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.7cac197cfe503p605,
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.1e5dfc140e1e5p716,
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.8ce85fadb707ep829,
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x1.95d5f3d928edep945};
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
303