Java tutorial
/* Copyright 2009-2015 David Hadka * * This file is part of the MOEA Framework. * * The MOEA Framework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * The MOEA Framework is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ package iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.tree; import org.apache.commons.math3.util.FastMath; import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.Settings; /** * Provides many arithmetic and trigonometric functions that operate on * {@link Number}s, performing any necessary implicit casting. An integer * number remains an integer unless the specific function requires * floating-point values. These methods favor {@link Long} and {@link Double} * representations for integer and floating-point values, respectively. * <p> * The arithmetic functions provided herein support optional function * protection, which is enabled by default. Function protection prevents * values like {@code Inf} and {@code NaN} from appearing due to invalid * inputs. For example, this protects against division-by-zero. To disable * function protection, set the property * {@code iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.tree.protected_functions = false} in the file * {@code global.properties}. {@code Inf} and {@code NaN} values can still * occur with function protection enabled, so outputs should still be * validated. */ public class NumberArithmetic { /** * Private constructor to prevent instantiation. */ private NumberArithmetic() { super(); } /** * Returns {@code true} if the two numbers are equal; {@code false} * otherwise. * * @param a the first number * @param b the second number * @return {@code true} if the two numbers are equal; {@code false} * otherwise */ public static boolean equals(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return a.doubleValue() == b.doubleValue(); } else { return a.longValue() == b.longValue(); } } /** * Returns {@code true} if the first number is less than the second; * {@code false} otherwise. * * @param a the first number * @param b the second number * @return {@code true} if the first number is less than the second; * {@code false} otherwise */ public static boolean lessThan(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return a.doubleValue() < b.doubleValue(); } else { return a.longValue() < b.longValue(); } } /** * Returns {@code true} if the first number is less than or equal to the * second; {@code false} otherwise. * * @param a the first number * @param b the second number * @return {@code true} if the first number is less than or equal to the * second; {@code false} otherwise */ public static boolean lessThanOrEqual(Number a, Number b) { return lessThan(a, b) || equals(a, b); } /** * Returns {@code true} if the first number is greater than the second; * {@code false} otherwise. * * @param a the first number * @param b the second number * @return {@code true} if the first number is greater than the second; * {@code false} otherwise */ public static boolean greaterThan(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return a.doubleValue() > b.doubleValue(); } else { return a.longValue() > b.longValue(); } } /** * Returns {@code true} if the first number is greater than or equal to the * second; {@code false} otherwise. * * @param a the first number * @param b the second number * @return {@code true} if the first number is greater than or equal to the * second; {@code false} otherwise */ public static boolean greaterThanOrEqual(Number a, Number b) { return greaterThan(a, b) || equals(a, b); } /** * Returns the value of adding the two numbers * * @param a the first number * @param b the second number * @return the value of adding the two numbers */ public static Number add(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return a.doubleValue() + b.doubleValue(); } else { return a.longValue() + b.longValue(); } } /** * Returns the square root of the number. If the number is less than zero * and function protection is enabled, this functions the square root of * the absolute value of the number. * * @param a the number * @return the square root of the number * @see Math#sqrt(double) */ public static Number sqrt(Number a) { if ((a.doubleValue() < 0.0) && Settings.isProtectedFunctions()) { return Math.sqrt(Math.abs(a.doubleValue())); } else { return Math.sqrt(a.doubleValue()); } } /** * Returns the value of the first number to the power of the second. * * @param a the first number * @param b the second number * @return the value of the first number to the power of the second * @see Math#pow(double, double) */ public static Number pow(Number a, Number b) { return Math.pow(a.doubleValue(), b.doubleValue()); } /** * Returns the value of subtracting the first from the second number. * * @param a the first number * @param b the second number * @return the value of subtracting the first from the second number */ public static Number sub(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return a.doubleValue() - b.doubleValue(); } else { return a.longValue() - b.longValue(); } } /** * Returns the value of multiplying the two numbers. * * @param a the first number * @param b the second number * @return the value of multiplying the two numbers */ public static Number mul(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return a.doubleValue() * b.doubleValue(); } else { return a.longValue() * b.longValue(); } } /** * Returns the value of dividing the first number by the second. If the * second argument is {@code 0} and function protection is enabled, this * function returns {@code 1} regardless of the first argument's value. * * @param a the first number * @param b the second number * @return the value of dividing the first number by the second */ public static Number div(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { if ((Math.abs(b.doubleValue()) < Settings.EPS) && Settings.isProtectedFunctions()) { return 1.0; } else { return a.doubleValue() / b.doubleValue(); } } else { if ((b.longValue() == 0) && Settings.isProtectedFunctions()) { return 1L; } else { return a.longValue() / b.longValue(); } } } /** * Returns the remainder from dividing the first number by the second. If * the second argument is {@code 0} and function protection is enabled, * this function returns {@code 0} regardless of the first argument's * value. * * @param a the first number * @param b the second number * @return the remainder from dividing the first number by the second */ public static Number mod(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { if ((Math.abs(b.doubleValue()) < Settings.EPS) && Settings.isProtectedFunctions()) { return 0.0; } else { return a.doubleValue() % b.doubleValue(); } } else { if ((b.longValue() == 0) && Settings.isProtectedFunctions()) { return 0L; } else { return a.longValue() % b.longValue(); } } } /** * Returns the largest integer value less than or equal to the given * number. * * @param a the number * @return the largest integer value less than or equal to the given * number * @see Math#floor(double) */ public static Number floor(Number a) { if (isFloatingPoint(a)) { return Math.floor(a.doubleValue()); } else { return a.longValue(); } } /** * Returns the smallest integer value greater than or equal to the given * number. * * @param a the number * @return the smallest integer value greater than or equal to the given * number * @see Math#ceil(double) */ public static Number ceil(Number a) { if (isFloatingPoint(a)) { return Math.ceil(a.doubleValue()); } else { return a.longValue(); } } /** * Returns the value of the number rounded to the nearest integer. * * @param a the number * @return the value of the number rounded to the nearest integer * @see Math#round(double) */ public static Number round(Number a) { if (isFloatingPoint(a)) { return Math.round(a.doubleValue()); } else { return a.longValue(); } } /** * Returns the absolute value of the number. * * @param a the number * @return the absolute value of the number * @see Math#abs(long) * @see Math#abs(double) */ public static Number abs(Number a) { if (isFloatingPoint(a)) { return Math.abs(a.doubleValue()); } else { return Math.abs(a.longValue()); } } /** * Returns the natural logarithm of the number. If the numbers is * negative and function protection is enabled, then this function returns * the natural logarithm of the absolute value of the number. If the * number is near zero and function protection is enabled, this function * returns {@code 0.0}. * * @param a the number * @return the natural logarithm of the number * @see Math#log(double) */ public static Number log(Number a) { if ((a.doubleValue() < Settings.EPS) && Settings.isProtectedFunctions()) { double value = Math.abs(a.doubleValue()); if (value < Settings.EPS) { return 0.0; } else { return Math.log(value); } } else { return Math.log(a.doubleValue()); } } /** * Returns the base-10 logarithm of the number. If the numbers is * negative and function protection is enabled, then this function returns * the base-10 logarithm of the absolute value of the number. If the * number is near zero and function protection is enabled, this function * returns {@code 0.0}. * * @param a the number * @return the base-10 logarithm of the number * @see Math#log10(double) */ public static Number log10(Number a) { if ((a.doubleValue() < Settings.EPS) && Settings.isProtectedFunctions()) { double value = Math.abs(a.doubleValue()); if (value < Settings.EPS) { return 0.0; } else { return Math.log10(value); } } else { return Math.log10(a.doubleValue()); } } /** * Returns the value from taking Euler's number <i>e</i> to the power of * the given number. * * @param a the number * @return the value from taking Euler's number <i>e</i> to the power of * the given number * @see Math#exp(double) */ public static Number exp(Number a) { return Math.exp(a.doubleValue()); } /** * Returns the trigonometric sine of the number. * * @param a the number * @return the trigonometric sine of the number * @see Math#sin(double) */ public static Number sin(Number a) { return Math.sin(a.doubleValue()); } /** * Returns the trigonometric cosine of the number. * * @param a the number * @return the trigonometric cosine of the number * @see Math#cos(double) */ public static Number cos(Number a) { return Math.cos(a.doubleValue()); } /** * Returns the trigonometric tangent of the number. * * @param a the number * @return the trigonometric tangent of the number * @see Math#tan(double) */ public static Number tan(Number a) { return Math.tan(a.doubleValue()); } /** * Returns the arc sine of the number. * * @param a the number * @return the arc sine of the number * @see Math#asin(double) */ public static Number asin(Number a) { return Math.asin(a.doubleValue()); } /** * Returns the arc cosine of the number. * * @param a the number * @return the arc cosine of the number * @see Math#acos(double) */ public static Number acos(Number a) { return Math.acos(a.doubleValue()); } /** * Returns the arc tangent of the number. * * @param a the number * @return the arc tangent of the number * @see Math#atan(double) */ public static Number atan(Number a) { return Math.atan(a.doubleValue()); } /** * Returns the hyperbolic sine of the number. * * @param a the number * @return the hyperbolic sine of the number * @see Math#sinh(double) */ public static Number sinh(Number a) { return Math.sinh(a.doubleValue()); } /** * Returns the hyperbolic cosine of the number. * * @param a the number * @return the hyperbolic cosine of the number * @see Math#cosh(double) */ public static Number cosh(Number a) { return Math.cosh(a.doubleValue()); } /** * Returns the hyperbolic tangent of the number. * * @param a the number * @return the hyperbolic tangent of the number * @see Math#tanh(double) */ public static Number tanh(Number a) { return Math.tanh(a.doubleValue()); } /** * Returns the hyperbolic arc sine of the number. * * @param a the number * @return the hyperbolic arc sine of the number * @see FastMath#asinh(double) */ public static Number asinh(Number a) { return FastMath.asinh(a.doubleValue()); } /** * Returns the hyperbolic arc cosine of the number. * * @param a the number * @return the hyperbolic arc cosine of the number * @see FastMath#acosh(double) */ public static Number acosh(Number a) { return FastMath.acosh(a.doubleValue()); } /** * Returns the hyperbolic arc tangent of the number. * * @param a the number * @return the hyperbolic arc tangent of the number * @see FastMath#atanh(double) */ public static Number atanh(Number a) { return FastMath.atanh(a.doubleValue()); } /** * Returns the maximum value of two numbers. * * @param a the first number * @param b the second number * @return the maximum value of two numbers * @see Math#min(long, long) * @see Math#min(double, double) */ public static Number max(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return Math.max(a.doubleValue(), b.doubleValue()); } else { return Math.max(a.longValue(), b.longValue()); } } /** * Returns the minimum value of two numbers. * * @param a the first number * @param b the second number * @return the minimum value of two numbers * @see Math#max(long, long) * @see Math#max(double, double) */ public static Number min(Number a, Number b) { if (isFloatingPoint(a) || isFloatingPoint(b)) { return Math.min(a.doubleValue(), b.doubleValue()); } else { return Math.min(a.longValue(), b.longValue()); } } /** * Returns the sign of the number. * * @param a the number * @return the sign of the number * @see Long#signum(long) * @see Math#signum(double) */ public static Number sign(Number a) { if (isFloatingPoint(a)) { return Math.signum(a.doubleValue()); } else { return Long.signum(a.longValue()); } } /** * Returns {@code true} if the number is a floating-point value; * {@code false} otherwise. * * @param a the number * @return {@code true} if the number is a floating-point value; * {@code false} otherwise */ public static boolean isFloatingPoint(Number a) { return (a instanceof Float) || (a instanceof Double); } }