📄 mathutils.java
字号:
* Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned</li> * </ul> * </p> * * @param n argument * @return <code>n!</code> * @throws IllegalArgumentException if n < 0 */ public static double factorialDouble(final int n) { if (n < 0) { throw new IllegalArgumentException("must have n >= 0 for n!"); } return Math.floor(Math.exp(factorialLog(n)) + 0.5); } /** * Returns the natural logarithm of n!. * <p> * <Strong>Preconditions</strong>: * <ul> * <li> <code>n >= 0</code> (otherwise * <code>IllegalArgumentException</code> is thrown)</li> * </ul></p> * * @param n argument * @return <code>n!</code> * @throws IllegalArgumentException if preconditions are not met. */ public static double factorialLog(final int n) { if (n < 0) { throw new IllegalArgumentException("must have n > 0 for n!"); } double logSum = 0; for (int i = 2; i <= n; i++) { logSum += Math.log((double)i); } return logSum; } /** * <p> * Gets the greatest common divisor of the absolute value of two numbers, * using the "binary gcd" method which avoids division and modulo * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef * Stein (1961). * </p> * * @param u a non-zero number * @param v a non-zero number * @return the greatest common divisor, never zero * @since 1.1 */ public static int gcd(int u, int v) { if (u * v == 0) { return (Math.abs(u) + Math.abs(v)); } // keep u and v negative, as negative integers range down to // -2^31, while positive numbers can only be as large as 2^31-1 // (i.e. we can't necessarily negate a negative number without // overflow) /* assert u!=0 && v!=0; */ if (u > 0) { u = -u; } // make u negative if (v > 0) { v = -v; } // make v negative // B1. [Find power of 2] int k = 0; while ((u & 1) == 0 && (v & 1) == 0 && k < 31) { // while u and v are // both even... u /= 2; v /= 2; k++; // cast out twos. } if (k == 31) { throw new ArithmeticException("overflow: gcd is 2^31"); } // B2. Initialize: u and v have been divided by 2^k and at least // one is odd. int t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; // t negative: u was odd, v may be even (t replaces v) // t positive: u was even, v is odd (t replaces u) do { /* assert u<0 && v<0; */ // B4/B3: cast out twos from t. while ((t & 1) == 0) { // while t is even.. t /= 2; // cast out twos } // B5 [reset max(u,v)] if (t > 0) { u = -t; } else { v = t; } // B6/B3. at this point both u and v should be odd. t = (v - u) / 2; // |u| larger: t positive (replace u) // |v| larger: t negative (replace v) } while (t != 0); return -u * (1 << k); // gcd is u*2^k } /** * Returns an integer hash code representing the given double value. * * @param value the value to be hashed * @return the hash code */ public static int hash(double value) { long bits = Double.doubleToLongBits(value); return (int)(bits ^ (bits >>> 32)); } /** * Returns an integer hash code representing the given double array value. * * @param value the value to be hashed (may be null) * @return the hash code * @since 1.2 */ public static int hash(double[] value) { if (value == null) { return 0; } int result = value.length; for (int i = 0; i < value.length; ++i) { result = result * 31 + hash(value[i]); } return result; } /** * For a byte value x, this method returns (byte)(+1) if x >= 0 and * (byte)(-1) if x < 0. * * @param x the value, a byte * @return (byte)(+1) or (byte)(-1), depending on the sign of x */ public static byte indicator(final byte x) { return (x >= ZB) ? PB : NB; } /** * For a double precision value x, this method returns +1.0 if x >= 0 and * -1.0 if x < 0. Returns <code>NaN</code> if <code>x</code> is * <code>NaN</code>. * * @param x the value, a double * @return +1.0 or -1.0, depending on the sign of x */ public static double indicator(final double x) { if (Double.isNaN(x)) { return Double.NaN; } return (x >= 0.0) ? 1.0 : -1.0; } /** * For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x < * 0. Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>. * * @param x the value, a float * @return +1.0F or -1.0F, depending on the sign of x */ public static float indicator(final float x) { if (Float.isNaN(x)) { return Float.NaN; } return (x >= 0.0F) ? 1.0F : -1.0F; } /** * For an int value x, this method returns +1 if x >= 0 and -1 if x < 0. * * @param x the value, an int * @return +1 or -1, depending on the sign of x */ public static int indicator(final int x) { return (x >= 0) ? 1 : -1; } /** * For a long value x, this method returns +1L if x >= 0 and -1L if x < 0. * * @param x the value, a long * @return +1L or -1L, depending on the sign of x */ public static long indicator(final long x) { return (x >= 0L) ? 1L : -1L; } /** * For a short value x, this method returns (short)(+1) if x >= 0 and * (short)(-1) if x < 0. * * @param x the value, a short * @return (short)(+1) or (short)(-1), depending on the sign of x */ public static short indicator(final short x) { return (x >= ZS) ? PS : NS; } /** * Returns the least common multiple between two integer values. * * @param a the first integer value. * @param b the second integer value. * @return the least common multiple between a and b. * @throws ArithmeticException if the lcm is too large to store as an int * @since 1.1 */ public static int lcm(int a, int b) { return Math.abs(mulAndCheck(a / gcd(a, b), b)); } /** * <p>Returns the * <a href="http://mathworld.wolfram.com/Logarithm.html">logarithm</a> * for base <code>b</code> of <code>x</code>. * </p> * <p>Returns <code>NaN<code> if either argument is negative. If * <code>base</code> is 0 and <code>x</code> is positive, 0 is returned. * If <code>base</code> is positive and <code>x</code> is 0, * <code>Double.NEGATIVE_INFINITY</code> is returned. If both arguments * are 0, the result is <code>NaN</code>.</p> * * @param base the base of the logarithm, must be greater than 0 * @param x argument, must be greater than 0 * @return the value of the logarithm - the number y such that base^y = x. * @since 1.2 */ public static double log(double base, double x) { return Math.log(x)/Math.log(base); } /** * Multiply two integers, checking for overflow. * * @param x a factor * @param y a factor * @return the product <code>x*y</code> * @throws ArithmeticException if the result can not be represented as an * int * @since 1.1 */ public static int mulAndCheck(int x, int y) { long m = ((long)x) * ((long)y); if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) { throw new ArithmeticException("overflow: mul"); } return (int)m; } /** * Multiply two long integers, checking for overflow. * * @param a first value * @param b second value * @return the product <code>a * b</code> * @throws ArithmeticException if the result can not be represented as an * long * @since 1.2 */ public static long mulAndCheck(long a, long b) { long ret; String msg = "overflow: multiply"; if (a > b) { // use symmetry to reduce boundry cases ret = mulAndCheck(b, a); } else { if (a < 0) { if (b < 0) { // check for positive overflow with negative a, negative b if (a >= Long.MAX_VALUE / b) { ret = a * b; } else { throw new ArithmeticException(msg); } } else if (b > 0) { // check for negative overflow with negative a, positive b if (Long.MIN_VALUE / b <= a) { ret = a * b; } else { throw new ArithmeticException(msg); } } else { // assert b == 0 ret = 0; } } else if (a > 0) { // assert a > 0 // assert b > 0 // check for positive overflow with positive a, positive b if (a <= Long.MAX_VALUE / b) { ret = a * b; } else { throw new ArithmeticException(msg); } } else { // assert a == 0 ret = 0; } } return ret; } /** * Get the next machine representable number after a number, moving * in the direction of another number. * <p> * If <code>direction</code> is greater than or equal to<code>d</code>, * the smallest machine representable number strictly greater than * <code>d</code> is returned; otherwise the largest representable number * strictly less than <code>d</code> is returned.</p> * <p> * If <code>d</code> is NaN or Infinite, it is returned unchanged.</p> * * @param d base number * @param direction (the only important thing is whether * direction is greater or smaller than d) * @return the next machine representable number in the specified direction * @since 1.2 */ public static double nextAfter(double d, double direction) { // handling of some important special cases if (Double.isNaN(d) || Double.isInfinite(d)) { return d; } else if (d == 0) { return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE; } // special cases MAX_VALUE to infinity and MIN_VALUE to 0 // are handled just as normal numbers // split the double in raw components long bits = Double.doubleToLongBits(d); long sign = bits & 0x8000000000000000L; long exponent = bits & 0x7ff0000000000000L; long mantissa = bits & 0x000fffffffffffffL; if (d * (direction - d) >= 0) { // we should increase the mantissa if (mantissa == 0x000fffffffffffffL) { return Double.longBitsToDouble(sign | (exponent + 0x0010000000000000L));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -