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

📄 mathutils.java

📁 Apache的common math数学软件包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.commons.math.util;import java.math.BigDecimal;/** * Some useful additions to the built-in functions in {@link Math}. * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $ */public final class MathUtils {    /** -1.0 cast as a byte. */    private static final byte  NB = (byte)-1;    /** -1.0 cast as a short. */    private static final short NS = (short)-1;    /** 1.0 cast as a byte. */    private static final byte  PB = (byte)1;    /** 1.0 cast as a short. */    private static final short PS = (short)1;    /** 0.0 cast as a byte. */    private static final byte  ZB = (byte)0;    /** 0.0 cast as a short. */    private static final short ZS = (short)0;    /** 2 &pi;. */    private static final double TWO_PI = 2 * Math.PI;    /**     * Private Constructor     */    private MathUtils() {        super();    }    /**     * Add two integers, checking for overflow.     *      * @param x an addend     * @param y an addend     * @return the sum <code>x+y</code>     * @throws ArithmeticException if the result can not be represented as an     *         int     * @since 1.1     */    public static int addAndCheck(int x, int y) {        long s = (long)x + (long)y;        if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {            throw new ArithmeticException("overflow: add");        }        return (int)s;    }    /**     * Add two long integers, checking for overflow.     *      * @param a an addend     * @param b an addend     * @return the sum <code>a+b</code>     * @throws ArithmeticException if the result can not be represented as an     *         long     * @since 1.2     */    public static long addAndCheck(long a, long b) {        return addAndCheck(a, b, "overflow: add");    }        /**     * Add two long integers, checking for overflow.     *      * @param a an addend     * @param b an addend     * @param msg the message to use for any thrown exception.     * @return the sum <code>a+b</code>     * @throws ArithmeticException if the result can not be represented as an     *         long     * @since 1.2     */    private static long addAndCheck(long a, long b, String msg) {        long ret;        if (a > b) {            // use symmetry to reduce boundry cases            ret = addAndCheck(b, a, msg);        } else {            // assert a <= b                        if (a < 0) {                if (b < 0) {                    // check for negative overflow                    if (Long.MIN_VALUE - b <= a) {                        ret = a + b;                    } else {                        throw new ArithmeticException(msg);                    }                } else {                    // oppisite sign addition is always safe                    ret = a + b;                }            } else {                // assert a >= 0                // assert b >= 0                // check for positive overflow                if (a <= Long.MAX_VALUE - b) {                    ret = a + b;                } else {                    throw new ArithmeticException(msg);                }            }        }        return ret;    }        /**     * Returns an exact representation of the <a     * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial     * Coefficient</a>, "<code>n choose k</code>", the number of     * <code>k</code>-element subsets that can be selected from an     * <code>n</code>-element set.     * <p>     * <Strong>Preconditions</strong>:     * <ul>     * <li> <code>0 <= k <= n </code> (otherwise     * <code>IllegalArgumentException</code> is thrown)</li>     * <li> The result is small enough to fit into a <code>long</code>. The     * largest value of <code>n</code> for which all coefficients are     * <code> < Long.MAX_VALUE</code> is 66. If the computed value exceeds     * <code>Long.MAX_VALUE</code> an <code>ArithMeticException     *      </code> is     * thrown.</li>     * </ul></p>     *      * @param n the size of the set     * @param k the size of the subsets to be counted     * @return <code>n choose k</code>     * @throws IllegalArgumentException if preconditions are not met.     * @throws ArithmeticException if the result is too large to be represented     *         by a long integer.     */    public static long binomialCoefficient(final int n, final int k) {        if (n < k) {            throw new IllegalArgumentException(                "must have n >= k for binomial coefficient (n,k)");        }        if (n < 0) {            throw new IllegalArgumentException(                "must have n >= 0 for binomial coefficient (n,k)");        }        if ((n == k) || (k == 0)) {            return 1;        }        if ((k == 1) || (k == n - 1)) {            return n;        }        long result = Math.round(binomialCoefficientDouble(n, k));        if (result == Long.MAX_VALUE) {            throw new ArithmeticException(                "result too large to represent in a long integer");        }        return result;    }    /**     * Returns a <code>double</code> representation of the <a     * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial     * Coefficient</a>, "<code>n choose k</code>", the number of     * <code>k</code>-element subsets that can be selected from an     * <code>n</code>-element set.     * <p>     * <Strong>Preconditions</strong>:     * <ul>     * <li> <code>0 <= k <= n </code> (otherwise     * <code>IllegalArgumentException</code> is thrown)</li>     * <li> The result is small enough to fit into a <code>double</code>. The     * largest value of <code>n</code> for which all coefficients are <     * Double.MAX_VALUE is 1029. If the computed value exceeds Double.MAX_VALUE,     * Double.POSITIVE_INFINITY is returned</li>     * </ul></p>     *      * @param n the size of the set     * @param k the size of the subsets to be counted     * @return <code>n choose k</code>     * @throws IllegalArgumentException if preconditions are not met.     */    public static double binomialCoefficientDouble(final int n, final int k) {        return Math.floor(Math.exp(binomialCoefficientLog(n, k)) + 0.5);    }        /**     * Returns the natural <code>log</code> of the <a     * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial     * Coefficient</a>, "<code>n choose k</code>", the number of     * <code>k</code>-element subsets that can be selected from an     * <code>n</code>-element set.     * <p>     * <Strong>Preconditions</strong>:     * <ul>     * <li> <code>0 <= k <= n </code> (otherwise     * <code>IllegalArgumentException</code> is thrown)</li>     * </ul></p>     *      * @param n the size of the set     * @param k the size of the subsets to be counted     * @return <code>n choose k</code>     * @throws IllegalArgumentException if preconditions are not met.     */    public static double binomialCoefficientLog(final int n, final int k) {        if (n < k) {            throw new IllegalArgumentException(                "must have n >= k for binomial coefficient (n,k)");        }        if (n < 0) {            throw new IllegalArgumentException(                "must have n >= 0 for binomial coefficient (n,k)");        }        if ((n == k) || (k == 0)) {            return 0;        }        if ((k == 1) || (k == n - 1)) {            return Math.log((double)n);        }        double logSum = 0;        // n!/k!        for (int i = k + 1; i <= n; i++) {            logSum += Math.log((double)i);        }        // divide by (n-k)!        for (int i = 2; i <= n - k; i++) {            logSum -= Math.log((double)i);        }        return logSum;    }        /**     * Returns the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html">     * hyperbolic cosine</a> of x.     *      * @param x double value for which to find the hyperbolic cosine     * @return hyperbolic cosine of x     */    public static double cosh(double x) {        return (Math.exp(x) + Math.exp(-x)) / 2.0;    }        /**     * Returns true iff both arguments are NaN or neither is NaN and they are     * equal     *      * @param x first value     * @param y second value     * @return true if the values are equal or both are NaN     */    public static boolean equals(double x, double y) {        return ((Double.isNaN(x) && Double.isNaN(y)) || x == y);    }    /**     * Returns true iff both arguments are null or have same dimensions     * and all their elements are {@link #equals(double,double) equals}     *      * @param x first array     * @param y second array     * @return true if the values are both null or have same dimension     * and equal elements     * @since 1.2     */    public static boolean equals(double[] x, double[] y) {        if ((x == null) || (y == null)) {            return !((x == null) ^ (y == null));        }        if (x.length != y.length) {            return false;        }        for (int i = 0; i < x.length; ++i) {            if (!equals(x[i], y[i])) {                return false;            }        }        return true;    }    /**     * Returns n!. Shorthand for <code>n</code> <a     * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the     * product of the numbers <code>1,...,n</code>.     * <p>     * <Strong>Preconditions</strong>:     * <ul>     * <li> <code>n >= 0</code> (otherwise     * <code>IllegalArgumentException</code> is thrown)</li>     * <li> The result is small enough to fit into a <code>long</code>. The     * largest value of <code>n</code> for which <code>n!</code> <     * Long.MAX_VALUE</code> is 20. If the computed value exceeds <code>Long.MAX_VALUE</code>     * an <code>ArithMeticException </code> is thrown.</li>     * </ul>     * </p>     *      * @param n argument     * @return <code>n!</code>     * @throws ArithmeticException if the result is too large to be represented     *         by a long integer.     * @throws IllegalArgumentException if n < 0     */    public static long factorial(final int n) {        long result = Math.round(factorialDouble(n));        if (result == Long.MAX_VALUE) {            throw new ArithmeticException(                "result too large to represent in a long integer");        }        return result;    }    /**     * Returns n!. Shorthand for <code>n</code> <a     * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the     * product of the numbers <code>1,...,n</code> as a <code>double</code>.     * <p>     * <Strong>Preconditions</strong>:     * <ul>     * <li> <code>n >= 0</code> (otherwise     * <code>IllegalArgumentException</code> is thrown)</li>     * <li> The result is small enough to fit into a <code>double</code>. The     * largest value of <code>n</code> for which <code>n!</code> <     * Double.MAX_VALUE</code> is 170. If the computed value exceeds

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -