/* * VLCMath.java * * */ package org.smartly.packages.velocity.impl.vtools; import org.smartly.commons.util.ConversionUtils; import org.smartly.commons.util.MathUtils; import org.smartly.commons.util.RandomUtils; import java.math.BigDecimal; import java.util.Collection; import java.util.List; /** * Tool utility for basic arithmetic operations. */ public class MathTool implements IVLCTool { public static final String NAME = "math"; /** * Creates a new instance of VLCMath */ public MathTool() { } @Override public String getName() { return NAME; } public Number inc(final Object num){ return this.sum(num, 1); } public Number dec(final Object num){ return this.sub(num,1); } /** * Sum a list of numbers in different formats (String, integer, BigDecimal, Decimal, etc..) * * @param numbers List of numbers to sum * @return BigDecimal */ public Number sum(List<Object> numbers) { BigDecimal result = BigDecimal.ZERO; for (Object number : numbers) { BigDecimal value; if (null != number) { value = ConversionUtils.toBigDecimal(number); } else { value = BigDecimal.ZERO; } result = result.add(value); } return result.doubleValue(); } public Number sum(final Object... numbers) { return MathUtils.add(numbers); } public Double divide(final Object dividend, final Object divisor) { final BigDecimal num1 = ConversionUtils.toBigDecimal(dividend); final BigDecimal num2 = ConversionUtils.toBigDecimal(divisor); final double result = num1.doubleValue() / num2.doubleValue(); return result; } public Integer divideIntValue(final Object dividend, final Object divisor) { final double result = this.divide(dividend, divisor); return this.intValue(result); } public Integer divideRoundCeil(final Object dividend, final Object divisor) { final double result = this.divide(dividend, divisor); return this.intValue(this.roundCeil(result)); } public Double multiply(final Object dividend, final Object divisor) { final BigDecimal num1 = ConversionUtils.toBigDecimal(dividend); final BigDecimal num2 = ConversionUtils.toBigDecimal(divisor); return num1.multiply(num2).doubleValue(); } public double sqrt(final Object value){ return Math.sqrt(ConversionUtils.toDouble(value)); } // -------------------------------------------------------------------- // R A N D O M // -------------------------------------------------------------------- public Integer randomInt(final int digits) { return RandomUtils.getTimeBasedRandomInteger(digits); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * <p/> * <p>Characters will be chosen from the set of alpha-numeric * characters as indicated by the arguments.</p> * * @param digits the length of random string to create * @return the random string */ public String randomString(final int digits) { return RandomUtils.random(digits, true, true); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * <p/> * <p>Characters will be chosen from the set of characters whose * ASCII value is between <code>32</code> and <code>126</code> (inclusive).</p> * * @param digits the length of random string to create * @return the random string */ public String randomAscii(final int digits) { return RandomUtils.randomAscii(digits); } /** * Return a random number with a limit range. * * @param min * @param max * @return */ public double random(final double min, final double max) { return RandomUtils.rnd(min, max); } /** * @return a pseudo-random {@link Double} greater * than or equal to 0.0 and less than 1.0 * @see java.lang.Math#random() */ public Double random() { return new Double(java.lang.Math.random()); } /** * This returns a random {@link Number} within the * specified range. The returned value will be * greater than or equal to the first number * and less than the second number. If both arguments * are whole numbers then the returned number will * also be, otherwise a {@link Double} will * be returned. * * @param num1 the first number * @param num2 the second number * @return a pseudo-random {@link Number} greater than * or equal to the first number and less than * the second * @see java.lang.Math#random() */ public Number random(Object num1, Object num2) { return RandomUtils.rnd(num1, num2); } // -------------------------------------------------------------------- // R O U N D // -------------------------------------------------------------------- /** * Round a number mantainig desired number of decimal digits.<br> * i.e. round(1.234, 2) = 1.23<br> * i.e. round(1.236, 2) = 1.24 * * @param value * @param decimals * @return */ public double round(final double value, final int decimals) { return MathUtils.round(value, decimals); } /** * Round ceil a number, mantaining desired decimals. * i.e. roundCeil(1.121, 2) = 1.13 * * @param value the value * @param decimals number of decimals digits * @return rounded value */ public double roundCeil(final double value, final int decimals) { return MathUtils.roundCeil(value, decimals); } /** * Round ceil a number, mantaining desired decimals. * i.e. roundCeil(1.121, 2) = 1.13 * * @param value the value * @param decimals number of decimals digits * @return rounded value */ public double roundCeil(final Object value, final int decimals) { final BigDecimal number = ConversionUtils.toBigDecimal(value); return this.roundCeil(number.doubleValue(), decimals); } public double roundCeil(final Object value) { final BigDecimal number = ConversionUtils.toBigDecimal(value); return this.roundCeil(number.doubleValue(), 0); } /** * Round floor a number, mantaining desired decimals. * i.e. roundFloor(1.129, 2) = 1.12 * * @param value the value * @param decimals number of decimals digits * @return rounded value */ public double roundFloor(final double value, final int decimals) { return MathUtils.roundFloor(value, decimals); } // -------------------------------------------------------------------- // MISC // -------------------------------------------------------------------- /** * Return integer part of a number * * @param value * @return */ public int intValue(final Object value) { final BigDecimal number = ConversionUtils.toBigDecimal(value); return number.intValue(); } /** * @param nums the numbers to be added * @return the sum of the numbers or * <code>null</code> if they're invalid * @see MathUtils#add(Object...) */ public Number add(Object... nums) { return MathUtils.add(nums); } /** * @param nums the numbers to be subtracted * @return the difference of the numbers (subtracted in order) or * <code>null</code> if they're invalid * @see MathUtils#sub(Object...) */ public Number sub(Object... nums) { return MathUtils.sub(nums); } /** * @param nums the numbers to be multiplied * @return the product of the numbers or * <code>null</code> if they're invalid * @see MathUtils#mul(Object...) */ public Number mul(Object... nums) { return MathUtils.mul(nums); } /** * @param nums the numbers to be divided * @return the quotient of the numbers or * <code>null</code> if they're invalid * or if any denominator equals zero * @see MathUtils#div(Object...) */ public Number div(Object... nums) { return MathUtils.div(nums); } /** * @param num1 the first number * @param num2 the second number * @return the first number raised to the power of the * second or <code>null</code> if they're invalid * @see MathUtils#pow(Object, Object) */ public Number pow(Object num1, Object num2) { return MathUtils.pow(num1, num2); } /** * Does integer division on the int values of the specified numbers. * <p/> * <p>So, $math.idiv('5.1',3) will return '1', * and $math.idiv(6,'3.9') will return '2'.</p> * * @param num1 the first number * @param num2 the second number * @return the result of performing integer division * on the operands. * @see MathUtils#idiv(Object, Object) */ public Integer idiv(Object num1, Object num2) { return MathUtils.idiv(num1, num2); } /** * Does integer modulus on the int values of the specified numbers. * <p/> * <p>So, $math.mod('5.1',3) will return '2', * and $math.mod(6,'3.9') will return '0'.</p> * * @param num1 the first number * @param num2 the second number * @return the result of performing integer modulus * on the operands. * @see MathUtils#mod(Object, Object) */ public Integer mod(Object num1, Object num2) { return MathUtils.mod(num1, num2); } /** * @param nums the numbers to be searched * @return the largest of the numbers or * <code>null</code> if they're invalid * @see MathUtils#max(Integer...) */ public Number max(Object... nums) { return MathUtils.max(nums); } /** * @param nums the numbers to be searched * @return the smallest of the numbers or * <code>null</code> if they're invalid * @see MathUtils#min(Object...) */ public Number min(Object... nums) { return MathUtils.min(nums); } public static double match(final Object value, final Object min, final Object max) { return MathUtils.matchLimit(value, min, max); } /** * @param num the number * @return the absolute value of the number or * <code>null</code> if it's invalid * @see MathUtils#abs(Object) */ public Number abs(Object num) { return MathUtils.abs(num); } /** * @param num the number * @return the smallest integer that is not * less than the given number * @see MathUtils#ceil(Object) */ public Integer ceil(Object num) { return MathUtils.ceil(num); } /** * @param num the number * @return the integer portion of the number * @see MathUtils#floor(Object) */ public Integer floor(final Object num) { return MathUtils.floor(num); } /** * Rounds a number to the nearest whole Integer * * @param num the number to round * @return the number rounded to the nearest whole Integer * or <code>null</code> if it's invalid * @see MathUtils#round(Object) */ public Integer round(final Object num) { return MathUtils.round(num); } /** * Rounds a number to the specified number of decimal places. * This is particulary useful for simple display formatting. * If you want to round an number to the nearest integer, it * is better to use {@link #round}, as that will return * an {@link Integer} rather than a {@link Double}. * * @param decimals the number of decimal places * @param num the number to round * @return the value rounded to the specified number of * decimal places or <code>null</code> if it's invalid * @see MathUtils#roundTo(Object, Object) */ public Double roundTo(Object num, Object decimals) { return MathUtils.roundTo(num, decimals); } // ------------------------- Aggregation methods ------------------ /** * Get the sum of the values from a list * * @param collection A collection containing Java beans * @param field A Java Bean field for the objects in <i>collection</i> that * will return a number. * @return The sum of the values in <i>collection</i>. */ public Number getTotal(Collection collection, String field) { return MathUtils.getTotal(collection, field); } /** * Get the average of the values from a list * * @param collection A collection containing Java beans * @param field A Java Bean field for the objects in <i>collection</i> that * will return a number. * @return The average of the values in <i>collection</i>. */ public Number getAverage(Collection collection, String field) { return MathUtils.getAverage(collection, field); } /** * Get the sum of the values from a list * * @param array An array containing Java beans * @param field A Java Bean field for the objects in <i>array</i> that * will return a number. * @return The sum of the values in <i>array</i>. */ public Number getTotal(Object[] array, String field) { return MathUtils.getTotal(array, field); } /** * Get the sum of the values from a list * * @param array A collection containing Java beans * @param field A Java Bean field for the objects in <i>array</i> that * will return a number. * @return The sum of the values in <i>array</i>. */ public Number getAverage(Object[] array, String field) { return MathUtils.getAverage(array, field); } /** * Get the sum of the values * * @param collection A collection containing numeric values * @return The sum of the values in <i>collection</i>. */ public Number getTotal(Collection collection) { return MathUtils.getTotal(collection); } /** * Get the average of the values * * @param collection A collection containing number values * @return The average of the values in <i>collection</i>. */ public Number getAverage(Collection collection) { return MathUtils.getAverage(collection); } /** * Get the sum of the values * * @param array An array containing number values * @return The sum of the values in <i>array</i>. */ public Number getTotal(Object... array) { return MathUtils.getTotal(array); } /** * Get the average of the values * * @param array An array containing number values * @return The sum of the values in <i>array</i>. */ public Number getAverage(Object... array) { return MathUtils.getAverage(array); } /** * Get the sum of the values * * @param values The list of double values to add up. * @return The sum of the arrays */ public Number getTotal(double... values) { return MathUtils.getTotal(values); } /** * Get the average of the values in an array of double values * * @param values The list of double values * @return The average of the array of values */ public Number getAverage(double... values) { return MathUtils.getAverage(values); } /** * Get the sum of the values * * @param values The list of long values to add up. * @return The sum of the arrays */ public Number getTotal(long... values) { return MathUtils.getTotal(values); } /** * Get the average of the values in an array of long values * * @param values The list of long values * @return The average of the array of values */ public Number getAverage(long... values) { return MathUtils.getAverage(values); } // --------------- public type conversion methods --------- /** * Converts an object with a numeric value into an Integer * Valid formats are {@link Number} or a {@link String} * representation of a number * * @param num the number to be converted * @return a {@link Integer} representation of the number * or <code>null</code> if it's invalid */ public Integer toInteger(Object num) { Number n = ConversionUtils.toNumber(num); if (n == null) { return null; } return Integer.valueOf(n.intValue()); } /** * Converts an object with a numeric value into a Double * Valid formats are {@link Number} or a {@link String} * representation of a number * * @param num the number to be converted * @return a {@link Double} representation of the number * or <code>null</code> if it's invalid */ public Double toDouble(Object num) { Number n = ConversionUtils.toNumber(num); if (n == null) { return null; } return new Double(n.doubleValue()); } // ------------------------------------------------------------------------ // p r i v a t e // ------------------------------------------------------------------------ }