All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.exactpro.sf.actions.MathUtil Maven / Gradle / Ivy

There is a newer version: 3.4.260
Show newest version
/******************************************************************************
 * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
 *
 * 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.exactpro.sf.actions;

import static com.exactpro.sf.util.FormatHelper.buildFormatString;
import static com.exactpro.sf.util.FormatHelper.formatDouble;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;

import com.exactpro.sf.aml.Description;
import com.exactpro.sf.common.util.EPSCommonException;
import com.exactpro.sf.configuration.ResourceAliases;
import com.exactpro.sf.scriptrunner.AbstractCaller;
import com.exactpro.sf.scriptrunner.utilitymanager.UtilityMethod;

@MatrixUtils
@ResourceAliases("MathUtil")
public class MathUtil extends AbstractCaller {

    private static final String ROUNDING_MODES = "Rounding Modes:
" + "UP - Rounding mode to round away from zero.
" + "Always increments the digit prior to a nonzero discarded fraction.
" + "DOWN - Rounding mode to round towards zero.
" + "Never increments the digit prior to a discarded fraction (i.e., truncates).
" + "HALF_UP - Rounding mode to round towards \"nearest neighbor\" unless both neighbors are equidistant,
" + " in which case round up. Behaves as for UP if the discarded fraction is ≥ 0.5; otherwise, behaves as for DOWN.
" + "HALF_DOWN - Rounding mode to round towards \"nearest neighbor\" unless both neighbors are equidistant,
" + " in which case round down. Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN.
" + "CEILING - Rounding mode to round towards positive infinity.
" + "If the value is positive, behaves as for UP; if negative, behaves as for DOWN.
" + "FLOOR - Rounding mode to round towards negative infinity.
" + "If the value is positive, behave as for DOWN; if negative, behave as for UP.
" + "HALF_EVEN, or \"Banker's rounding\" - Rounding mode to round towards \"nearest neighbor\" unless both neighbors are equidistant,
" + " in which case, round towards the even neighbor.
" + "UNNECESSARY - Rounding mode to assert that the requested operation has an exact result,
" + " hence no rounding is necessary.
"; @Description("Returns the smallest (closest to negative infinity) double value that is greater than or equal to the argument and is equal to a mathematical integer.
" + "Special cases:
" + "If the argument value is already equal to a mathematical integer, then the result is the same as the argument.
" + "If the argument is NaN or an infinity or positive zero or negative zero, then the result is the same as the argument.
" + "If the argument value is less than zero but greater than -1.0, then the result is negative zero.
" + "Note that the value of Math.ceil(x) is exactly the value of -Math.floor(-x).
" + "d - a double value for ceiling.
" + "Example:
" + "#{ceil(-5.1)} returns -5.0
" + "#{ceil(5.1)} returns 6.0") @UtilityMethod public double ceil(double d) { return Math.ceil(d); } @Description("Returns the smallest (closest to negative infinity) double value that is greater than or equal to the argument and is equal to a mathematical integer.
" + "If the argument is not negative, the argument is returned.
" + "If the argument is negative, the negation of the argument is returned.
" + "Special cases:
" + "If the argument is positive zero or negative zero, the result is positive zero.
" + "If the argument is infinite, the result is positive infinity.
" + "If the argument is NaN, the result is NaN.
" + "d - a double value for obtaining the absolute value.
" + "Example:
" + "#{abs(-5.0)} returns 5.0") @UtilityMethod public double abs(double d) { return Math.abs(d); } @Description("Returns the absolute value of a float value.
" + "If the argument is not negative, the argument is returned.
" + "If the argument is negative, the negation of the argument is returned.
" + "Special cases:
" + "If the argument is positive zero or negative zero, the result is positive zero.
" + "If the argument is infinite, the result is positive infinity.
" + "If the argument is NaN, the result is NaN.
" + "f - a float value for obtaining the absolute value.
" + "Example:
" + "#{abs(-5.0f)} returns 5.0") @UtilityMethod public float abs(float f) { return Math.abs(f); } @Description("Returns the absolute value of a long value.
" + "If the argument is not negative, the argument is returned.
" + "If the argument is negative, the negation of the argument is returned.
" + "i - an integer value for obtaining the absolute value.
" + "Example:
" + "#{abs(-5)} returns 5") @UtilityMethod public int abs(int i) { return Math.abs(i); } @Description("Returns the absolute value of a int value.
" + "If the argument is not negative, the argument is returned.
" + "If the argument is negative, the negation of the argument is returned.
" + "l - a long value for obtaining the absolute value.
" + "Example:
" + "#{abs(-555555555l)} returns 555555555") @UtilityMethod public long abs(long l) { return Math.abs(l); } @Description("Returns the absolute value of a BigDecimal value.
" + "If the argument is not negative, the argument is returned.
" + "If the argument is negative, the negation of the argument is returned.
" + "b - a BigDecimal value for obtaining the absolute value.
" + "Example:
" + "#{abs(-5.0B)} returns 5.0") @UtilityMethod public BigDecimal abs(BigDecimal b) { return b.abs(); } @Description("Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer.
" + "Special cases:
" + "If the argument value is already equal to a mathematical integer, then the result is the same as the argument.
" + "If the argument is NaN or infinity or positive zero or negative zero, then the result is the same as the argument.
" + "d - a double value for flooring.
" + "Example:
" + "#{floor(-5.1)} returns -6.0
" + "#{floor(5.1)} returns 5.0") @UtilityMethod public double floor(double d) { return Math.floor(d); } @Description("Returns the floating-point value adjacent to d in the direction of positive infinity.
" + "This method is semantically equivalent to nextAfter(d, Double.POSITIVE_INFINITY); however, a nextUp implementation may run faster than its equivalent nextAfter call.
" + "Special Cases:
" + "If the argument is NaN, the result is NaN.
" + "If the argument is positive infinity, the result is positive infinity.
" + "If the argument is zero, the result is Double.MIN_VALUE
" + "d - a double value for increase.
" + "Example:
" + "#{nextUp(5.0)} returns 5.000000000000001") @UtilityMethod public double nextUp(double d) { return Math.nextUp(d); } @Description("Returns the minimum of the values
" + "numbers - values for comparison. Must be of the same type
" + "Example:
" + "#{min(5, 4, 3)} returns 3") @UtilityMethod public Object min(Object ... numbers){ try { Arrays.sort(numbers); } catch (ClassCastException e) { StringBuilder builder = new StringBuilder("Input params have different types:"); for (Object o:numbers) { builder.append(o.getClass().getSimpleName()); builder.append(", "); } throw new EPSCommonException(builder.toString()); } return numbers[0]; } @Description("Returns the maximum of the values
" + "numbers - values for comparison. Must be of the same type
" + "Example:
" + "#{max(5, 4, 3)} returns 5") @UtilityMethod public Object max(Object ... numbers){ try { Arrays.sort(numbers); } catch (ClassCastException e) { StringBuilder builder = new StringBuilder("Input params have different types:"); for (Object o:numbers) { builder.append(o.getClass().getSimpleName()); builder.append(", "); } throw new EPSCommonException(builder.toString()); } return numbers[numbers.length - 1]; } @Description("Returns the minimum of the int values
" + "numbers - integer values for comparison
" + "Example:
" + "#{minInt(5, 4, 3)} returns 3") @UtilityMethod public int minInt(int ... numbers){ Arrays.sort(numbers); return numbers[0]; } @Description("Returns the maximum of the int values
" + "numbers - integer values for comparison
" + "Example:
" + "#{maxInt(5, 4, 3)} returns 5") @UtilityMethod public int maxInt(int ... numbers){ Arrays.sort(numbers); return numbers[numbers.length - 1]; } @Description("Returns the minimum of the long values
" + "numbers - long integer values for comparison
" + "Example:
" + "#{minLong(55555555555l, 44444444444l, 33333333333l)} returns 33333333333") @UtilityMethod public long minLong(long ... numbers){ Arrays.sort(numbers); return numbers[0]; } @Description("Returns the maximum of the long values
" + "numbers - long integer values for comparison
" + "Example:
" + "#{maxLong(55555555555l, 44444444444l, 33333333333l)} returns 55555555555") @UtilityMethod public long maxLong(long ... numbers){ Arrays.sort(numbers); return numbers[numbers.length - 1]; } @Description("Returns the minimum of the char values
" + "numbers - char values for comparison
" + "Example:
" + "#{minChar('1', '0', '2')} returns '0'") @UtilityMethod public char minChar(char ... numbers){ Arrays.sort(numbers); return numbers[0]; } @Description("Returns the maximum of the char values
" + "numbers - char values for comparison
" + "Example:
" + "#{minChar('1', '0', '2')} returns '2'") @UtilityMethod public char maxChar(char ... numbers){ Arrays.sort(numbers); return numbers[numbers.length - 1]; } @Description("Returns the minimum of the double values
" + "numbers - double values for comparison
" + "Example:
" + "#{minDouble(5.0, 4.0, 3.0)} returns 3.0") @UtilityMethod public double minDouble(double ... numbers){ Arrays.sort(numbers); return numbers[0]; } @Description("Returns the maximum of the double values
" + "numbers - double values for comparison
" + "Example:
" + "#{minDouble(5.0, 4.0, 3.0)} returns 5.0") @UtilityMethod public double maxDouble(double ... numbers){ Arrays.sort(numbers); return numbers[numbers.length - 1]; } @Description("Returns the minimum of the BigDecimal values
" + "numbers - BigDecimal values for comparison
" + "Example:
" + "#{minBigDecimal(5.0B, 4.0B, 3.0B)} returns 3.0") @UtilityMethod public BigDecimal minBigDecimal(BigDecimal... numbers){ Arrays.sort(numbers); return numbers[0]; } @Description("Returns the maximum of the BigDecimal values
" + "numbers - BigDecimal values for comparison
" + "Example:
" + "#{maxBigDecimal(5.0B, 4.0B, 3.0B)} returns 5.0") @UtilityMethod public BigDecimal maxBigDecimal(BigDecimal... numbers){ Arrays.sort(numbers); return numbers[numbers.length - 1]; } @Description("Rounds d with specified precision
" + "d - double value for rounding
" + "precision - the number of digits after the decimal separator
" + "Example:
" + "#{round(5.4564638, 4)} returns 5.4565") @UtilityMethod public double round(double d, int precision) { String formatString = buildFormatString(precision); return formatDouble(formatString, d); } @Description("Rounds d with specified precision
" + "d - BigDecimal value for rounding
" + "precision - the number of digits after the decimal separator
" + "Example:
" + "#{round(5.4564638B, 4)} returns 5.4565") @UtilityMethod public BigDecimal round(BigDecimal d, int precision) { return d.setScale(precision, RoundingMode.HALF_UP); } @Description("Rounds d with specified precision
" + "d - double value for rounding
" + "precision - the number of digits after the decimal separator
" + ROUNDING_MODES + "Example:
" + "#{round(5.4564638, 4, \"HALF_UP\")} returns 5.4565") @UtilityMethod public Double round(Double d, int precision, String roundingMode) { BigDecimal bd = BigDecimal.valueOf(d); bd = bd.setScale(precision, RoundingMode.valueOf(roundingMode.toUpperCase())); return bd.doubleValue(); } @Description("Rounds d with specified precision
" + "d - BigDecimal value for rounding
" + "precision - the number of digits after the decimal separator
" + ROUNDING_MODES + "Example:
" + "#{round(5.4564638, 4, \"HALF_UP\")} returns 5.4565") @UtilityMethod public BigDecimal round(BigDecimal d, int precision, String roundingMode) { return d.setScale(precision, RoundingMode.valueOf(roundingMode.toUpperCase())); } @Description("Returns a rounded by precision and direction number
" + "value - rounding value.
" + "direction = 0 - the value will be rounded down.
" + "direction = 1 - the value will be rounded up.
" + "direction = 2 - arithmetic rounding
" + "precision - symbols of the value double are set to zero, starting from the position precision. Must be positive.
" + "Example:
" + "#{round_zero(12345,1,0)} returns 12340
" + "#{round_zero(12345,1,1)} returns 12350
" + "#{round_zero(12345,1,2)} returns 12350") @UtilityMethod public double roundZero(double value, int precision, int direction){ switch (direction){ case 0:return roundDown((long)value, (int)Math.pow(10, precision)); case 1:return roundUp((long)value, (int)Math.pow(10, precision)); case 2:return round((long)value, (int)Math.pow(10, precision)); default:return round((long)value, (int)Math.pow(10, precision)); } } @Description("Rounds the double to an integer value using round away from zero mode
" + "value - rounding value.
" + "Example:
" + "#{roundUp(-1.001)} returns -2") @UtilityMethod public int roundUp(double value) { return round(value, 0, RoundingMode.UP.toString()).intValue(); } private static long round(long num, int multiplier) { return (int) (((num / (double) multiplier) - num / multiplier) * 10) >= 5 ? roundUp(num, multiplier) : roundDown(num, multiplier); } private static long roundUp(long num, int multiplier) { return (num / multiplier) * multiplier + multiplier; } private static long roundDown(long num, int multiplier) { return (num / multiplier) * multiplier; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy