⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mathutils.java

📁 Apache的common math数学软件包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * 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 + -