/** * Copyright (C) 2014-2020 Philip Helger (www.helger.com) * philip[at]helger[dot]com * * Licensed 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 com.helger.commons.math; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnegative; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import com.helger.commons.CGlobal; import com.helger.commons.ValueEnforcer; import com.helger.commons.annotation.PresentForCodeCoverage; import com.helger.commons.equals.EqualsHelper; /** * Contains several math help routines. * * @author Philip Helger */ @Immutable public final class MathHelper { private static final long LONG_HIGH_BITS = 0xFFFFFFFF80000000L; @PresentForCodeCoverage private static final MathHelper s_aInstance = new MathHelper (); private MathHelper () {} /** * Round up to the nearest multiple of the value to round. * * @param nToRound * Value to round. May be positive or negative. * @param nMultiple * Multiple to use. Must be ≥ 0. * @return The rounded value. */ public static int getRoundedUp (final int nToRound, @Nonnegative final int nMultiple) { if (nMultiple == 0) return nToRound; final int nRest = nToRound % nMultiple; if (nRest == 0) return nToRound; if (nToRound < 0) return -abs (nToRound - nRest); return nToRound + nMultiple - nRest; } /** * Divides the passed int dividend through the passed divisor (nDividend / * nDivisor) * * @param nDividend * the dividend * @param nDivisor * the divisor * @return a double representing the exact quotient. Returns * {@link Double#NaN} if the divisor is 0. */ public static double getDividedDouble (final int nDividend, final int nDivisor) { final double dDividend = nDividend; final double dDivisor = nDivisor; return dDividend / dDivisor; } /** * Divides the passed int dividend through the passed divisor (nDividend / * nDivisor) * * @param nDividend * the dividend * @param nDivisor * the divisor * @return a double representing the exact quotient. Returns * {@link Double#NaN} if the divisor is 0. */ public static double getDividedDouble (final long nDividend, final long nDivisor) { final double dDividend = nDividend; final double dDivisor = nDivisor; return dDividend / dDivisor; } /** * Get the division result using {@link BigDecimal}. * * @param nDividend * the dividend * @param nDivisor * the divisor * @return the result of the division * @throws ArithmeticException * if the divisor is 0. */ @Nonnull public static BigDecimal getDividedBigDecimal (final long nDividend, final long nDivisor) { final BigDecimal aDividend = BigDecimal.valueOf (nDividend); final BigDecimal aDivisor = BigDecimal.valueOf (nDivisor); return aDividend.divide (aDivisor); } public static int getIntDividedCeil (final int nDividend, final int nDivisor) { return getIntDivided (nDividend, nDivisor, RoundingMode.CEILING); } public static int getIntDividedFloor (final int nDividend, final int nDivisor) { return getIntDivided (nDividend, nDivisor, RoundingMode.FLOOR); } public static int getIntDivided (final int nDividend, final int nDivisor, @Nonnull final RoundingMode eRoundingMode) { return toBigDecimal (nDividend).divide (toBigDecimal (nDivisor), eRoundingMode).intValue (); } public static long getLongDividedCeil (final long nDividend, final long nDivisor) { return getLongDivided (nDividend, nDivisor, RoundingMode.CEILING); } public static long getLongDividedFloor (final long nDividend, final long nDivisor) { return getLongDivided (nDividend, nDivisor, RoundingMode.FLOOR); } public static long getLongDivided (final long nDividend, final long nDivisor, @Nonnull final RoundingMode eRoundingMode) { return toBigDecimal (nDividend).divide (toBigDecimal (nDivisor), eRoundingMode).longValue (); } public static boolean canConvertLongToInt (final long nValue) { return (nValue & LONG_HIGH_BITS) == 0 || (nValue & LONG_HIGH_BITS) == LONG_HIGH_BITS; } @CheckReturnValue public static int getLongAsInt (final long nValue, final int nFallback) { return canConvertLongToInt (nValue) ? (int) nValue : nFallback; } public static int getMaxInt (final int nValue, @Nonnull final int... aValues) { int ret = nValue; for (final int n : aValues) ret = Math.max (ret, n); return ret; } public static long getMaxLong (final long nValue, @Nonnull final long... aValues) { long ret = nValue; for (final long n : aValues) ret = Math.max (ret, n); return ret; } public static double getMaxFloat (final float fValue, @Nonnull final float... aValues) { float ret = fValue; for (final float f : aValues) ret = Math.max (ret, f); return ret; } public static double getMaxDouble (final double dValue, @Nonnull final double... aValues) { double ret = dValue; for (final double d : aValues) ret = Math.max (ret, d); return ret; } @Nonnull public static BigDecimal getMaxBigDecimal (@Nonnull final BigDecimal aValue, @Nonnull final BigDecimal... aValues) { BigDecimal ret = aValue; for (final BigDecimal a : aValues) if (a.compareTo (ret) > 0) ret = a; return ret; } @Nonnull public static BigInteger getMaxBigInteger (@Nonnull final BigInteger aValue, @Nonnull final BigInteger... aValues) { BigInteger ret = aValue; for (final BigInteger a : aValues) if (a.compareTo (ret) > 0) ret = a; return ret; } public static int getMinInt (final int nValue, @Nonnull final int... aValues) { int ret = nValue; for (final int n : aValues) ret = Math.min (ret, n); return ret; } public static long getMinLong (final long nValue, @Nonnull final long... aValues) { long ret = nValue; for (final long n : aValues) ret = Math.min (ret, n); return ret; } public static double getMinFloat (final float fValue, @Nonnull final float... aValues) { float ret = fValue; for (final float f : aValues) ret = Math.min (ret, f); return ret; } public static double getMinDouble (final double dValue, @Nonnull final double... aValues) { double ret = dValue; for (final double d : aValues) ret = Math.min (ret, d); return ret; } @Nonnull public static BigDecimal getMinBigDecimal (@Nonnull final BigDecimal aValue, @Nonnull final BigDecimal... aValues) { BigDecimal ret = aValue; for (final BigDecimal a : aValues) if (a.compareTo (ret) < 0) ret = a; return ret; } @Nonnull public static BigInteger getMinBigInteger (@Nonnull final BigInteger aValue, @Nonnull final BigInteger... aValues) { BigInteger ret = aValue; for (final BigInteger a : aValues) if (a.compareTo (ret) < 0) ret = a; return ret; } /** * This is a fix for <code>Math.abs</code> as it would return * {@link Integer#MIN_VALUE} for {@link Integer#MIN_VALUE} which is very * unexpected. Instead an exception is thrown. * * @param nValue * Input value * @return the absolute value of the argument. * @throws IllegalArgumentException * if the input value is {@link Integer#MIN_VALUE} */ @Nonnegative public static int abs (final int nValue) { // As Integer.MIN_VALUE is -2^31 and Integer.MAX_VALUE is 2^31-1 it means // that there is not integer value matching 2^31!!! if (nValue == Integer.MIN_VALUE) throw new IllegalArgumentException ("There is not absolute value for Integer.MIN_VALUE!"); return Math.abs (nValue); } /** * This is a fix for <code>Math.abs</code> as it would return * {@link Long#MIN_VALUE} for {@link Long#MIN_VALUE} which is very unexpected. * Instead an exception is thrown. * * @param nValue * Input value * @return the absolute value of the argument. * @throws IllegalArgumentException * if the input value is {@link Long#MIN_VALUE} */ @Nonnegative public static long abs (final long nValue) { // As Long.MIN_VALUE is -2^63 and Integer.MAX_VALUE is 2^63-1 it means // that there is not integer value matching 2^63!!! if (nValue == Long.MIN_VALUE) throw new IllegalArgumentException ("There is not absolute value for Long.MIN_VALUE!"); return Math.abs (nValue); } /** * This is a sanity method wrapping <code>Math.abs (float)</code>, so that you * don't have to think whether you need to invoke the abs method from this * class or the one from Math directly. * * @param fValue * Input value * @return the absolute value of the argument. */ @Nonnegative public static float abs (final float fValue) { return Math.abs (fValue); } /** * This is a sanity method wrapping <code>Math.abs (double)</code>, so that * you don't have to think whether you need to invoke the abs method from this * class or the one from Math directly. * * @param dValue * Input value * @return the absolute value of the argument. */ @Nonnegative public static double abs (final double dValue) { return Math.abs (dValue); } /** * This is a sanity method wrapping <code>BigDecimal.abs (double)</code>, so * that you don't have to think whether you need to invoke the abs method from * this class or the one from BigDecimal directly. * * @param aValue * Input value * @return the absolute value of the argument. */ @Nonnull public static BigDecimal abs (@Nonnull final BigDecimal aValue) { return aValue.abs (); } /** * This is a sanity method wrapping <code>BigInteger.abs (double)</code>, so * that you don't have to think whether you need to invoke the abs method from * this class or the one from BigInteger directly. * * @param aValue * Input value * @return the absolute value of the argument. */ @Nonnull public static BigInteger abs (@Nonnull final BigInteger aValue) { return aValue.abs (); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 0. */ public static boolean isEQ0 (@Nonnull final BigDecimal aValue) { return EqualsHelper.equals (aValue, BigDecimal.ZERO); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 0. */ public static boolean isNE0 (@Nonnull final BigDecimal aValue) { return !EqualsHelper.equals (aValue, BigDecimal.ZERO); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 0. */ public static boolean isLT0 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ZERO) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 0. */ public static boolean isLE0 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ZERO) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 0. */ public static boolean isGT0 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ZERO) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 0. */ public static boolean isGE0 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ZERO) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 1. */ public static boolean isEQ1 (@Nonnull final BigDecimal aValue) { return EqualsHelper.equals (aValue, BigDecimal.ONE); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 1. */ public static boolean isNE1 (@Nonnull final BigDecimal aValue) { return !EqualsHelper.equals (aValue, BigDecimal.ONE); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 1. */ public static boolean isLT1 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ONE) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 1. */ public static boolean isLE1 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ONE) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 1. */ public static boolean isGT1 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ONE) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 1. */ public static boolean isGE1 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.ONE) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 10. */ public static boolean isEQ10 (@Nonnull final BigDecimal aValue) { return EqualsHelper.equals (aValue, BigDecimal.TEN); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 10. */ public static boolean isNE10 (@Nonnull final BigDecimal aValue) { return !EqualsHelper.equals (aValue, BigDecimal.TEN); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 10. */ public static boolean isLT10 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.TEN) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 10. */ public static boolean isLE10 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.TEN) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 10. */ public static boolean isGT10 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.TEN) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 10. */ public static boolean isGE10 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (BigDecimal.TEN) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 100. */ public static boolean isEQ100 (@Nonnull final BigDecimal aValue) { return EqualsHelper.equals (aValue, CGlobal.BIGDEC_100); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 100. */ public static boolean isNE100 (@Nonnull final BigDecimal aValue) { return !EqualsHelper.equals (aValue, CGlobal.BIGDEC_100); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 100. */ public static boolean isLT100 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (CGlobal.BIGDEC_100) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 100. */ public static boolean isLE100 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (CGlobal.BIGDEC_100) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 100. */ public static boolean isGT100 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (CGlobal.BIGDEC_100) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 100. */ public static boolean isGE100 (@Nonnull final BigDecimal aValue) { return aValue.compareTo (CGlobal.BIGDEC_100) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 0. */ public static boolean isEQ0 (@Nonnull final BigInteger aValue) { return EqualsHelper.equals (aValue, BigInteger.ZERO); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 0. */ public static boolean isNE0 (@Nonnull final BigInteger aValue) { return !EqualsHelper.equals (aValue, BigInteger.ZERO); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 0. */ public static boolean isLT0 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ZERO) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 0. */ public static boolean isLE0 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ZERO) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 0. */ public static boolean isGT0 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ZERO) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 0. */ public static boolean isGE0 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ZERO) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 1. */ public static boolean isEQ1 (@Nonnull final BigInteger aValue) { return EqualsHelper.equals (aValue, BigInteger.ONE); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 1. */ public static boolean isNE1 (@Nonnull final BigInteger aValue) { return !EqualsHelper.equals (aValue, BigInteger.ONE); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 1. */ public static boolean isLT1 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ONE) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 1. */ public static boolean isLE1 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ONE) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 1. */ public static boolean isGT1 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ONE) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 1. */ public static boolean isGE1 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.ONE) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 10. */ public static boolean isEQ10 (@Nonnull final BigInteger aValue) { return EqualsHelper.equals (aValue, BigInteger.TEN); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 10. */ public static boolean isNE10 (@Nonnull final BigInteger aValue) { return !EqualsHelper.equals (aValue, BigInteger.TEN); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 10. */ public static boolean isLT10 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.TEN) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 10. */ public static boolean isLE10 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.TEN) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 10. */ public static boolean isGT10 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.TEN) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 10. */ public static boolean isGE10 (@Nonnull final BigInteger aValue) { return aValue.compareTo (BigInteger.TEN) >= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is = 100. */ public static boolean isEQ100 (@Nonnull final BigInteger aValue) { return EqualsHelper.equals (aValue, CGlobal.BIGINT_100); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is != 100. */ public static boolean isNE100 (@Nonnull final BigInteger aValue) { return !EqualsHelper.equals (aValue, CGlobal.BIGINT_100); } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is < 100. */ public static boolean isLT100 (@Nonnull final BigInteger aValue) { return aValue.compareTo (CGlobal.BIGINT_100) < 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≤ 100. */ public static boolean isLE100 (@Nonnull final BigInteger aValue) { return aValue.compareTo (CGlobal.BIGINT_100) <= 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is > 100. */ public static boolean isGT100 (@Nonnull final BigInteger aValue) { return aValue.compareTo (CGlobal.BIGINT_100) > 0; } /** * @param aValue * Value to compare. May not be <code>null</code>. * @return <code>true</code> if the value is ≥ 100. */ public static boolean isGE100 (@Nonnull final BigInteger aValue) { return aValue.compareTo (CGlobal.BIGINT_100) >= 0; } /** * Get the passed String as a BigDecimal without any trailing zeroes. * * @param sValue * The String to be used as a BigDecimal to be modified. May be * <code>null</code>. * @return <code>null</code> if the input value is <code>null</code>. */ @Nullable @CheckReturnValue public static BigDecimal getWithoutTrailingZeroes (@Nullable final String sValue) { if (sValue == null) return null; return getWithoutTrailingZeroes (new BigDecimal (sValue)); } /** * Get the passed BigDecimal without any trailing zeroes. Examples: * <ul> * <li>new BigDecimal ("0.00000000") --> 0</li> * <li>new BigDecimal ("10") --> 10</li> * <li>new BigDecimal ("10.00000000") --> 10</li> * <li>new BigDecimal ("10.1") --> 10.1</li> * <li>new BigDecimal ("10.10000000") --> 10.1</li> * <li>new BigDecimal ("10.345") --> 10.345</li> * <li>new BigDecimal ("10.3450000000") --> 10.345</li> * </ul> * * @param aValue * The BigDecimal to be modified. May be <code>null</code>. * @return <code>null</code> if the input value is <code>null</code>. */ @Nullable @CheckReturnValue public static BigDecimal getWithoutTrailingZeroes (@Nullable final BigDecimal aValue) { if (aValue == null) return null; // stripTrailingZeros does not work for "0"! if (BigDecimal.ZERO.compareTo (aValue) == 0) return BigDecimal.ZERO; final BigDecimal ret = aValue.stripTrailingZeros (); // Avoid stuff like "6E2" return ret.scale () >= 0 ? ret : ret.setScale (0); } /** * Get the number of effective fraction digits by the specified BigDecimal. * Examples: * <ul> * <li>new BigDecimal ("10") --> 0</li> * <li>new BigDecimal ("10.00000000") --> 0</li> * <li>new BigDecimal ("10.1") --> 1</li> * <li>new BigDecimal ("10.10000000") --> 1</li> * <li>new BigDecimal ("10.345") --> 3</li> * <li>new BigDecimal ("10.3450000000") --> 3</li> * </ul> * * @param aBD * The BigDecimal to check. May not be <code>null</code>. * @return The minimum number of fraction digits. Always ≥ 0. */ @Nonnegative public static int getFractionDigits (@Nonnull final BigDecimal aBD) { return getWithoutTrailingZeroes (aBD).scale (); } /** * Add x% to base * * @param aBase * Base value. May not be <code>null</code>. * @param aPercentage * Percentage value (0-100). May not be <code>null</code>. * @return base + x% (<code>=aBase * (100 + perc) / 100</code>). Never * <code>null</code>. */ @Nonnull public static BigDecimal addPercent (@Nonnull final BigDecimal aBase, @Nonnull final BigDecimal aPercentage) { return aBase.multiply (CGlobal.BIGDEC_100.add (aPercentage)).divide (CGlobal.BIGDEC_100); } /** * Add x% to base * * @param aBase * Base value. May not be <code>null</code>. * @param aPercentage * Percentage value (0-100). May not be <code>null</code>. * @param nScale * Maximum scale to achieve. * @param eRoundingMode * Rounding mode to used. May not be <code>null</code>. * @return base + x% (<code>=aBase * (100 + perc) / 100</code>). Never * <code>null</code>. */ @Nonnull public static BigDecimal addPercent (@Nonnull final BigDecimal aBase, @Nonnull final BigDecimal aPercentage, @Nonnegative final int nScale, @Nonnull final RoundingMode eRoundingMode) { return aBase.multiply (CGlobal.BIGDEC_100.add (aPercentage)).divide (CGlobal.BIGDEC_100, nScale, eRoundingMode); } /** * Subtract x% from base * * @param aBase * Base value. May not be <code>null</code>. * @param aPercentage * Percentage value (0-100). May not be <code>null</code>. * @return base - x% (<code>=aBase * (100 - perc) / 100</code>). Never * <code>null</code>. */ @Nonnull public static BigDecimal subtractPercent (@Nonnull final BigDecimal aBase, @Nonnull final BigDecimal aPercentage) { return aBase.multiply (CGlobal.BIGDEC_100.subtract (aPercentage)).divide (CGlobal.BIGDEC_100); } /** * Subtract x% from base * * @param aBase * Base value. May not be <code>null</code>. * @param aPercentage * Percentage value (0-100). May not be <code>null</code>. * @param nScale * Maximum scale to achieve. * @param eRoundingMode * Rounding mode to used. May not be <code>null</code>. * @return base - x% (<code>=aBase * (100 - perc) / 100</code>). Never * <code>null</code>. */ @Nonnull public static BigDecimal subtractPercent (@Nonnull final BigDecimal aBase, @Nonnull final BigDecimal aPercentage, @Nonnegative final int nScale, @Nonnull final RoundingMode eRoundingMode) { return aBase.multiply (CGlobal.BIGDEC_100.subtract (aPercentage)) .divide (CGlobal.BIGDEC_100, nScale, eRoundingMode); } /** * Get x% from base * * @param aBase * Base value. May not be <code>null</code>. * @param aPercentage * Percentage value (0-100). May not be <code>null</code>. * @return x% from base (<code>=aBase * perc / 100</code>). Never * <code>null</code>. */ @Nonnull public static BigDecimal getPercentValue (@Nonnull final BigDecimal aBase, @Nonnull final BigDecimal aPercentage) { return aBase.multiply (aPercentage).divide (CGlobal.BIGDEC_100); } /** * Get x% from base with rounding etc. * * @param aBase * Base value. May not be <code>null</code>. * @param aPercentage * Percentage value (0-100). May not be <code>null</code>. * @param nScale * Maximum scale to achieve. * @param eRoundingMode * Rounding mode to used. May not be <code>null</code>. * @return x% from base (<code>=aBase * perc / 100</code>). Never * <code>null</code>. */ @Nonnull public static BigDecimal getPercentValue (@Nonnull final BigDecimal aBase, @Nonnull final BigDecimal aPercentage, @Nonnegative final int nScale, @Nonnull final RoundingMode eRoundingMode) { return aBase.multiply (aPercentage).divide (CGlobal.BIGDEC_100, nScale, eRoundingMode); } /** * @param a * a * @param b * b * @return sqrt(a*a + b*b) without under/overflow. */ public static double hypot (final double a, final double b) { if (a == 0) return b; if (b == 0) return a; double r; final double dAbsA = abs (a); final double dAbsB = abs (b); if (dAbsA > dAbsB) { r = b / a; r = dAbsA * Math.sqrt (1 + r * r); } else { r = a / b; r = dAbsB * Math.sqrt (1 + r * r); } return r; } /** * Converts the passed signed integer to an unsigned long * * @param n * Source int * @return The unsigned long */ public static long getUnsignedInt (final int n) { return n & 0x00000000ffffffffL; } @Nonnull public static BigDecimal toBigDecimal (final int n) { // Compared to new BigDecimal(n) this may return constants return BigDecimal.valueOf (n); } @Nonnull public static BigDecimal toBigDecimal (final long n) { // Compared to new BigDecimal(n) this may return constants return BigDecimal.valueOf (n); } @Nonnull public static BigDecimal toBigDecimal (final float f) { return BigDecimal.valueOf (f); } @Nonnull public static BigDecimal toBigDecimal (final double d) { return BigDecimal.valueOf (d); } @Nonnull public static BigDecimal toBigDecimal (@Nonnull final Number aNumber) { ValueEnforcer.notNull (aNumber, "Number"); return new BigDecimal (aNumber.toString ()); } @Nonnull public static BigDecimal toBigDecimal (@Nonnull final String sNumber) { ValueEnforcer.notNull (sNumber, "Number"); return new BigDecimal (sNumber); } @Nonnull public static BigInteger toBigInteger (final int n) { return BigInteger.valueOf (n); } @Nonnull public static BigInteger toBigInteger (final long n) { return BigInteger.valueOf (n); } @Nonnull public static BigInteger toBigInteger (@Nonnull final Number aNumber) { ValueEnforcer.notNull (aNumber, "Number"); return new BigInteger (aNumber.toString (), 10); } @Nonnull public static BigInteger toBigInteger (@Nonnull final String sNumber) { ValueEnforcer.notNull (sNumber, "Number"); return new BigInteger (sNumber, 10); } /** * Check if only a single bit is set.<br> * Source: * http://stackoverflow.com/questions/12483843/test-if-a-bitboard-have-only-one-bit-set-to-1 * <br> * Say n has any bits set, the least significant is bit number k. Then n-1 has * the same bits as n for indices above k, a 0-bit in place k and 1-bits in * the less significant places, so the bitwise and removes the least * significant set bit from n. If n had only one bit set, the result becomes * 0, if n had more bits set, the result is nonzero. * * @param n * Source number * @return <code>true</code> if exactly one bit is set */ public static boolean isExactlyOneBitSetToOne (final int n) { return n != 0 && (n & (n - 1)) == 0; } /** * Check if only a single bit is set.<br> * Source: * http://stackoverflow.com/questions/12483843/test-if-a-bitboard-have-only-one-bit-set-to-1 * <br> * Say n has any bits set, the least significant is bit number k. Then n-1 has * the same bits as n for indices above k, a 0-bit in place k and 1-bits in * the less significant places, so the bitwise and removes the least * significant set bit from n. If n had only one bit set, the result becomes * 0, if n had more bits set, the result is nonzero. * * @param n * Source number * @return <code>true</code> if exactly one bit is set */ public static boolean isExactlyOneBitSetToOne (final long n) { return n != 0 && (n & (n - 1)) == 0; } }