package org.rr.commons.utils;
import static org.rr.commons.utils.StringUtil.EMPTY;
import java.io.Serializable;
public final class MathUtils implements Serializable {
private static final long serialVersionUID = -3880152775090057372L;
private MathUtils() {}
public static final int TYPE_0 = 0 ;
public static final int TYPE_1 = 1 ;
public static final int TYPE_2 = 2 ;
public static final int TYPE_3 = 3 ;
public static final int TYPE_4 = 4 ;
/**
* Round a double value to the next closest number considing the specified number of decimal places.
*
* @param value The number to be rounded.
* @param places Specifies how many places to the right of the decimal are included in the rounding.
* @return The rounded value.
*/
public static final double round(double value, int places) {
long factor = (long)Math.pow(10,places);
// Shift the decimal the correct number of places to the right.
value = value * factor;
return (double) Math.round(value) / factor;
}
/**
* Round a double value to the next greater number considing the specified number of decimal places.
*
* @param value The number to be rounded.
* @param places Specifies how many places to the right of the decimal are included in the rounding.
* @return The rounded value.
*/
public static final double roundUp(double value, int places) {
long factor = (long)Math.pow(10,places);
// Shift the decimal the correct number of places to the right.
value = value * factor;
return (double) Math.ceil(value) / factor;
}
/**
* Round a double value to the next smaller number considing the specified number of decimal places.
*
* @param value The number to be rounded.
* @param places Specifies how many places to the right of the decimal are included in the rounding.
* @return The rounded value.
*/
public static final double roundDown(double value, int places) {
long factor = (long)Math.pow(10,places);
// Shift the decimal the correct number of places to the right.
value = value * factor;
return (double) Math.floor(value) / factor;
}
/**
* Creates a string that represents the hexadecimal value of a specified number.
*
* If number is not a whole number, it is rounded to the nearest whole number before being evaluated.
* @param value The number to be used for calculation.
* @return The hex <code>String</code> from the given number.
*/
public static final String hex(double value) {
value = round(value, 0);
return Integer.toHexString((int)value).toUpperCase();
}
/**
* Creates a string that represents the octal value of a specified number.
*
* If number is not a whole number, it is rounded to the nearest whole number before being evaluated.
* @param value The number to be used for calculation.
* @return The hex <code>String</code> from the given number.
*/
public static final String oct(double value) {
value = round(value, 0);
return Integer.toOctalString((int)value);
}
/**
* Just truncates the the rest after the decimal point.
*
* @param value The value to be truncated.
* @return The truncated value.
*/
public static final int fix(double value) {
String stringValue = String.valueOf(value);
int index = stringValue.indexOf('.');
if (index!=-1) {
stringValue = stringValue.substring(0, index);
return Integer.parseInt(stringValue);
} else {
return (int) value;
}
}
/**
* Creates an integer that indicates the sign of a specified number.
*
* @param value A value to be determined if it has a positive or negative sign.
* @return If the specified number is:
* <ul>
* <li> >0 - Sgn returns 1</li>
* <li> =0 - Sgn returns 0</li>
* <li> <0 - Sgn returns -1</li>
*/
public static final int sgn(double value) {
if (value>0) {
return 1;
} else if (value<0) {
return -1;
} else {
return 0;
}
}
/**
* Calulates a random value with a specified upper and lower <code>int</code> value.
*
* @param lower The lower value.
* @param upper The lower value.
* @return A random value between the specified upper and lower value.
*/
public static int random(int lower, int upper) {
return (int)(Math.random() * (double)((upper - lower) + 1)) + lower;
}
/**
* Gets the factorial of a number
*
* @param number
* The number, of which the factorial should be calculated
* @return the factorial of the number
*/
public static double fact(double number) {
if (number < 0) {
throw new RuntimeException("Negative value");
}
double zaehler = 1;
double result = 1;
for (; zaehler <= number; zaehler++) {
result = result * zaehler;
}
return result;
}
/**
* Gets the polynominal of a group of numbers
*
* @param numbers
* The numbers of which the polynomial should be calculated
* @return The polynominal of the numbers
*/
public static double polynomial(double[] numbers) {
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] < 1) {
throw new RuntimeException("Negative value");
}
}
double first = 0;
double second = 1;
for (int i = 0; i < numbers.length; i++) {
first = first + numbers[i];
}
for (int j = 0; j < numbers.length; j++) {
second = second * fact(numbers[j]);
}
return (fact(first)) / (second);
}
/**
* Gets the factorial of a number with a step lenght of 2
*
* @param number
* The number of which the factorial should be calculated
* @return The factorial of the number with a step lenght of 2
*/
public static double factdouble(double number) {
if (number < 0) {
throw new RuntimeException("Negative value");
}
double zaehler = 0;
if (number % 2 == 0) {
zaehler = 2;
} else if (number % 2 == 1) {
zaehler = 1;
}
double result = number;
for (; zaehler <= number - 2; zaehler = zaehler + 2) {
result = result * (zaehler);
}
return result;
}
/**
* Translates a arabic number to a roman number
*
* @param number
* Is the arabic number which has to be translated
* @param type
* Sets the type of the roman number <br>
* Parameters could be:<br>
* <li>TYPE_0 : classic </li>
* <li>TYPE_1 : shorter </li>
* <li>TYPE_2 : shorter </li>
* <li>TYPE_3 : shorter </li>
* <li>TYPE_4 : simplified</li>
* @return The roman number as a text
*/
public static String roman(double number, int type) {
if (number < 0) {
throw new RuntimeException("Negative value");
}
if (number > 3999) {
throw new RuntimeException("Value too high " + number);
}
if (type == TYPE_0) {
return type0Roemisch(number);
} else if (type == TYPE_1) {
return type1Roemisch(number);
} else if (type == TYPE_2) {
return type2Roemisch(number);
} else if (type == TYPE_3) {
return type3Roemisch(number);
} else if (type == TYPE_4) {
return type4Roemisch(number);
} else {
return EMPTY;
}
}
/**
* Translates a arabic number to a roman number in <code>TYPE_0</code>
*
* @param number
* Is the arabic number which has to be translated
* @return The roman number as a text in the <code>TYPE_0</code>
*/
//englisch
private static String type0Roemisch(double number) {
String result = EMPTY;
while (number > 0) {
if (number > 1000 || number == 1000) {
result = result + "M";
number = number - 1000;
} else if (number > 900 || number == 900) {
result = result + "CM";
number = number - 900;
} else if (number > 500 || number == 500) {
result = result + "D";
number = number - 500;
} else if (number > 400 || number == 400) {
result = result + "CD";
number = number - 400;
} else if (number > 100 || number == 100) {
result = result + "C";
number = number - 100;
} else if (number > 90 || number == 90) {
result = result + "XC";
number = number - 90;
} else if (number > 50 || number == 50) {
result = result + "L";
number = number - 50;
} else if (number > 40 || number == 40) {
result = result + "XL";
number = number - 40;
} else if (number > 10 || number == 10) {
result = result + "X";
number = number - 10;
} else if (number > 9 || number == 9) {
result = result + "IX";
number = number - 9;
} else if (number > 5 || number == 5) {
result = result + "V";
number = number - 5;
} else if (number > 4 || number == 4) {
result = result + "IV";
number = number - 4;
} else if (number > 1 || number == 1) {
result = result + "I";
number = number - 1;
}
}
return result;
}
/**
* Translates a arabic number to a roman number in <code>TYPE_1</code>
*
* @param number
* Is the arabic number which has to be translated
* @return The roman number as a text in the <code>TYPE_1</code>
*/
//type terminus
private static String type1Roemisch(double number) {
String result = EMPTY;
while (number > 0) {
if (number > 1000 || number == 1000) {
result = result + "M";
number = number - 1000;
} else if (number > 950 || number == 950) {
result = result + "LM";
number = number - 950;
} else if (number > 900 || number == 900) {
result = result + "CM";
number = number - 900;
} else if (number > 500 || number == 500) {
result = result + "D";
number = number - 500;
} else if (number > 450 || number == 450) {
result = result + "LD";
number = number - 450;
} else if (number > 400 || number == 400) {
result = result + "CD";
number = number - 400;
} else if (number > 100 || number == 100) {
result = result + "C";
number = number - 100;
} else if (number > 95 || number == 95) {
result = result + "VC";
number = number - 95;
} else if (number > 90 || number == 90) {
result = result + "XC";
number = number - 90;
} else if (number > 50 || number == 50) {
result = result + "L";
number = number - 50;
} else if (number > 45 || number == 45) {
result = result + "VL";
number = number - 45;
} else if (number > 40 || number == 40) {
result = result + "XL";
number = number - 40;
} else if (number > 10 || number == 10) {
result = result + "X";
number = number - 10;
} else if (number > 9 || number == 9) {
result = result + "IX";
number = number - 9;
} else if (number > 5 || number == 5) {
result = result + "V";
number = number - 5;
} else if (number > 4 || number == 4) {
result = result + "IV";
number = number - 4;
} else if (number > 1 || number == 1) {
result = result + "I";
number = number - 1;
}
}
return result;
}
/**
* Translates a arabic number to a roman number in <code>TYPE_2</code>
*
* @param number
* Is the arabic number which has to be translated
* @return The roman number as a text in the <code>TYPE_2</code>
*/
private static String type2Roemisch(double number) {
String result = EMPTY;
while (number > 0) {
if (number > 1000 || number == 1000) {
result = result + "M";
number = number - 1000;
} else if (number > 990 || number == 990) {
result = result + "XM";
number = number - 990;
} else if (number > 950 || number == 950) {
result = result + "LM";
number = number - 950;
} else if (number > 900 || number == 900) {
result = result + "CM";
number = number - 900;
} else if (number > 500 || number == 500) {
result = result + "D";
number = number - 500;
} else if (number > 490 || number == 490) {
result = result + "XD";
number = number - 490;
} else if (number > 450 || number == 450) {
result = result + "LD";
number = number - 450;
} else if (number > 400 || number == 400) {
result = result + "CD";
number = number - 400;
} else if (number > 100 || number == 100) {
result = result + "C";
number = number - 100;
} else if (number > 95 || number == 95) {
result = result + "VC";
number = number - 95;
} else if (number > 90 || number == 90) {
result = result + "XC";
number = number - 90;
} else if (number > 50 || number == 50) {
result = result + "L";
number = number - 50;
} else if (number > 45 || number == 45) {
result = result + "VL";
number = number - 45;
} else if (number > 40 || number == 40) {
result = result + "XL";
number = number - 40;
} else if (number > 10 || number == 10) {
result = result + "X";
number = number - 10;
} else if (number > 9 || number == 9) {
result = result + "IX";
number = number - 9;
} else if (number > 5 || number == 5) {
result = result + "V";
number = number - 5;
} else if (number > 4 || number == 4) {
result = result + "IV";
number = number - 4;
} else if (number > 1 || number == 1) {
result = result + "I";
number = number - 1;
}
}
return result;
}
/**
* Translates a arabic number to a roman number in <code>TYPE_3</code>
*
* @param number
* Is the arabic number which has to be translated
* @return The roman number as a text in the <code>TYPE_3</code>
*/
private static String type3Roemisch(double number) {
String result = EMPTY;
while (number > 0) {
if (number > 1000 || number == 1000) {
result = result + "M";
number = number - 1000;
} else if (number > 995 || number == 995) {
result = result + "VM";
number = number - 995;
} else if (number > 990 || number == 990) {
result = result + "XM";
number = number - 990;
} else if (number > 950 || number == 950) {
result = result + "LM";
number = number - 950;
} else if (number > 900 || number == 900) {
result = result + "CM";
number = number - 900;
} else if (number > 500 || number == 500) {
result = result + "D";
number = number - 500;
} else if (number > 495 || number == 495) {
result = result + "VD";
number = number - 495;
} else if (number > 490 || number == 490) {
result = result + "XD";
number = number - 490;
} else if (number > 450 || number == 450) {
result = result + "LD";
number = number - 450;
} else if (number > 400 || number == 400) {
result = result + "CD";
number = number - 400;
} else if (number > 100 || number == 100) {
result = result + "C";
number = number - 100;
} else if (number > 95 || number == 95) {
result = result + "VC";
number = number - 95;
} else if (number > 90 || number == 90) {
result = result + "XC";
number = number - 90;
} else if (number > 50 || number == 50) {
result = result + "L";
number = number - 50;
} else if (number > 45 || number == 45) {
result = result + "VL";
number = number - 45;
} else if (number > 40 || number == 40) {
result = result + "XL";
number = number - 40;
} else if (number > 10 || number == 10) {
result = result + "X";
number = number - 10;
} else if (number > 9 || number == 9) {
result = result + "IX";
number = number - 9;
} else if (number > 5 || number == 5) {
result = result + "V";
number = number - 5;
} else if (number > 4 || number == 4) {
result = result + "IV";
number = number - 4;
} else if (number > 1 || number == 1) {
result = result + "I";
number = number - 1;
}
}
return result;
}
/**
* Translates a arabic number to a roman number in <code>TYPE_4</code>
*
* @param number
* Is the arabic number which has to be translated
* @return The roman number as a text in the <code>TYPE_4</code>
*/
private static String type4Roemisch(double number) {
String result = EMPTY;
while (number > 0) {
if (number > 1000 || number == 1000) {
result = result + "M";
number = number - 1000;
} else if (number > 999 || number == 999) {
result = result + "IM";
number = number - 999;
} else if (number > 995 || number == 995) {
result = result + "VM";
number = number - 995;
} else if (number > 990 || number == 990) {
result = result + "XM";
number = number - 990;
} else if (number > 950 || number == 950) {
result = result + "LM";
number = number - 950;
} else if (number > 900 || number == 900) {
result = result + "CM";
number = number - 900;
} else if (number > 500 || number == 500) {
result = result + "D";
number = number - 500;
} else if (number > 500 || number == 500) {
result = result + "D";
number = number - 500;
} else if (number > 499 || number == 499) {
result = result + "ID";
number = number - 499;
} else if (number > 490 || number == 490) {
result = result + "XD";
number = number - 490;
} else if (number > 450 || number == 450) {
result = result + "LD";
number = number - 450;
} else if (number > 400 || number == 400) {
result = result + "CD";
number = number - 400;
} else if (number > 100 || number == 100) {
result = result + "C";
number = number - 100;
} else if (number > 95 || number == 95) {
result = result + "VC";
number = number - 95;
} else if (number > 90 || number == 90) {
result = result + "XC";
number = number - 90;
} else if (number > 50 || number == 50) {
result = result + "L";
number = number - 50;
} else if (number > 45 || number == 45) {
result = result + "VL";
number = number - 45;
} else if (number > 40 || number == 40) {
result = result + "XL";
number = number - 40;
} else if (number > 10 || number == 10) {
result = result + "X";
number = number - 10;
} else if (number > 9 || number == 9) {
result = result + "IX";
number = number - 9;
} else if (number > 5 || number == 5) {
result = result + "V";
number = number - 5;
} else if (number > 4 || number == 4) {
result = result + "IV";
number = number - 4;
} else if (number > 1 || number == 1) {
result = result + "I";
number = number - 1;
}
}
return result;
}
/**
* Gets the integer part of a division
*
* @param numerator
* Is the dividend
* @param denominator
* Is the divisor
* @return The result of the division as a integer
*/
public static int quotient(double numerator, double denominator) {
if(denominator==0){
throw new RuntimeException("Negative value");
}
return (int) (numerator / denominator);
}
/**
* Gets the sum of powers
*
* @param x
* Is the value of the variables of the power series
* @param n
* Is the first power you want x to upraise
* @param m
* Is the increment you want n to extend in every link
* @param a
* A group of coefficients you want to multipliy x
* @return The sum of the power series
*/
public static double powerseries(double x, double n, double m, double[] a) {
double result = 0;
for (int i = 0; i < a.length; i++) {
result = result + a[i] * Math.pow(x, n + (m * i));
}
return result;
}
/**
* Rounds a number to the next integer value or to the next multiple of
* Schritt
*
* @param value
* The value which has to be rounded
* @param step
* The value of which multiple has to be rounded
* @return The rounded value
*/
public static double ceiling(double value, double step) {
if ((value < 0 && step > 0) || (value > 0 && step < 0)) {
throw new RuntimeException("Negative value");
}
double result = 0;
double zwresult = value / step;
if (value % step == 0) {
result = value;
} else {
result = step * Math.ceil(zwresult);
}
return result;
}
/**
* Gets the number of combinations of n with k elements
*
* @param n
* Is the total number of elements
* @param k
* Sets how much elements in one combination have to be
* @return The number of combinations
*/
public static double combin(double n, double k) {
if (k < 0 || n < 0) {
throw new RuntimeException("Negative value");
}
if (n < k) {
throw new RuntimeException("Wrong value for n " + n);
}
return fact(n) / (fact(k) * fact(n - k));
}
/**
* Converts degrees in radian
*
* @param angle
* Degrees to convert
* @return Value which represents the radian
*/
public static double radians(double angle) {
return (angle * Math.PI) / 180;
}
/**
* Gets the square root of the number which is multiplied with pi
*
* @param number
* Is the number which has to ber multiplied with pi
* @return The square root of the number
*/
public static double sqrtpi(double number) {
if (number < 0) {
throw new RuntimeException("Negative value");
}
return Math.sqrt(number * Math.PI);
}
/**
* Gets the variance of the array values
* @param values The values of which the variance should be calculated
* @return The variance of a value
*/
public static double variance(double values[]){
double sum=0;
for(int i=0;i<values.length;i++){
sum=sum+Math.pow(values[i],2);
}
double sum2=0;
for(int i=0;i<values.length;i++){
sum2=sum2+values[i];
}
double result=(values.length*sum-Math.pow(sum2,2)) / (Math.pow(values.length,2));
return result;
}
/**
* Calculates the inverse of the given value.
* @param value Value to be calculated
* @return The inverse of the given value.
*/
public static double inv(double value) {
return 1. / value;
}
/**
* Determines if the specified <code>value</code> is between the <code>firstScope</code>
* and the <code>secondScope</code> value.
*
* @param value Value to be tested
* @param firstScope The first value which specifies the range where the <code>value</code> is to be tested.
* @param secondScope The second value which specifies the range where the <code>value</code> is to be tested.
* @return <code>true</code> if the <code>value</code> is between the <code>firstScope</code> and <code>secondScope</code>
* value and <code>false</code> otherwise.
*/
public static boolean between(double value, double firstScope, double secondScope) {
if (value > firstScope && value < secondScope) {
return true;
}
if (value > secondScope && value < firstScope) {
return true;
}
return false;
}
/**
* Determines if the specified <code>value</code> is between the <code>minScope</code>
* and the <code>maxScope</code> value and returns a value which is in the defined scope.
*
* @param value Value to be tested
* @param minScope The max range specification.
* @param maxScope The min rage specification
* @return The value which is in the specified range.
*/
public static int range(int value, int minScope, int maxScope) {
if (value > minScope && value < maxScope) {
return value;
}
if (value > maxScope) {
return maxScope;
} else {
return minScope;
}
}
/**
* Calculates the difference between the two values specified with the
* patameters <code>value1</code> and <code>value2</code>. The result
* is a positive value in any case.
*
* @param value1 First value which differenc should be caluclated
* @param value2 Second value which differenc should be caluclated
* @return The difference between the two values.
*/
public static double difference(double value1, double value2) {
if (value1 > value2) {
return value1 - value2;
} else {
return value2 - value1;
}
}
}