📄 mathutils.java
字号:
* @return constant indicating type of Number to use in calculations
*/
private static int findCalculationBase (Number op1, Number op2)
{
boolean op1Int = isInteger(op1);
boolean op2Int = isInteger(op2);
if ( (op1 instanceof BigDecimal || op2 instanceof BigDecimal) ||
( (!op1Int || !op2Int) && (op1 instanceof BigInteger || op2 instanceof BigInteger)) )
{
return BASE_BIGDECIMAL;
}
if (op1Int && op2Int) {
if (op1 instanceof BigInteger || op2 instanceof BigInteger)
{
return BASE_BIGINTEGER;
}
return BASE_LONG;
}
if ((op1 instanceof Double) || (op2 instanceof Double))
{
return BASE_DOUBLE;
}
return BASE_FLOAT;
}
/**
* Add two numbers and return the correct value / type.
* Overflow detection is done for integer values (byte, short, int, long) only!
* @param op1
* @param op2
* @return Addition result.
*/
public static Number add (Number op1, Number op2)
{
int calcBase = findCalculationBase( op1, op2);
switch (calcBase)
{
case BASE_BIGINTEGER:
return toBigInteger( op1 ).add( toBigInteger( op2 ));
case BASE_LONG:
long l1 = op1.longValue();
long l2 = op2.longValue();
long result = l1+l2;
// Overflow check
if ((result ^ l1) < 0 && (result ^ l2) < 0)
{
return toBigInteger( op1).add( toBigInteger( op2));
}
return wrapPrimitive( result, op1, op2);
case BASE_FLOAT:
return new Float (op1.floatValue()+op2.floatValue());
case BASE_DOUBLE:
return new Double (op1.doubleValue()+op2.doubleValue());
// Default is BigDecimal operation
default:
return toBigDecimal( op1 ).add( toBigDecimal( op2 ));
}
}
/**
* Subtract two numbers and return the correct value / type.
* Overflow detection is done for integer values (byte, short, int, long) only!
* @param op1
* @param op2
* @return Subtraction result.
*/
public static Number subtract (Number op1, Number op2) {
int calcBase = findCalculationBase( op1, op2);
switch (calcBase) {
case BASE_BIGINTEGER:
return toBigInteger( op1 ).subtract( toBigInteger( op2 ));
case BASE_LONG:
long l1 = op1.longValue();
long l2 = op2.longValue();
long result = l1-l2;
// Overflow check
if ((result ^ l1) < 0 && (result ^ ~l2) < 0) {
return toBigInteger( op1).subtract( toBigInteger( op2));
}
return wrapPrimitive( result, op1, op2);
case BASE_FLOAT:
return new Float (op1.floatValue()-op2.floatValue());
case BASE_DOUBLE:
return new Double (op1.doubleValue()-op2.doubleValue());
// Default is BigDecimal operation
default:
return toBigDecimal( op1 ).subtract( toBigDecimal( op2 ));
}
}
/**
* Multiply two numbers and return the correct value / type.
* Overflow detection is done for integer values (byte, short, int, long) only!
* @param op1
* @param op2
* @return Multiplication result.
*/
public static Number multiply (Number op1, Number op2) {
int calcBase = findCalculationBase( op1, op2);
switch (calcBase) {
case BASE_BIGINTEGER:
return toBigInteger( op1 ).multiply( toBigInteger( op2 ));
case BASE_LONG:
long l1 = op1.longValue();
long l2 = op2.longValue();
long result = l1*l2;
// Overflow detection
if ((l2 != 0) && (result / l2 != l1)) {
return toBigInteger( op1).multiply( toBigInteger( op2));
}
return wrapPrimitive( result, op1, op2);
case BASE_FLOAT:
return new Float (op1.floatValue()*op2.floatValue());
case BASE_DOUBLE:
return new Double (op1.doubleValue()*op2.doubleValue());
// Default is BigDecimal operation
default:
return toBigDecimal( op1 ).multiply( toBigDecimal( op2 ));
}
}
/**
* Divide two numbers. The result will be returned as Integer-type if and only if
* both sides of the division operator are Integer-types. Otherwise a Float, Double,
* or BigDecimal will be returned.
* @param op1
* @param op2
* @return Division result.
*/
public static Number divide (Number op1, Number op2) {
int calcBase = findCalculationBase( op1, op2);
switch (calcBase) {
case BASE_BIGINTEGER:
BigInteger b1 = toBigInteger( op1 );
BigInteger b2 = toBigInteger( op2 );
return b1.divide( b2);
case BASE_LONG:
long l1 = op1.longValue();
long l2 = op2.longValue();
return wrapPrimitive( l1 / l2, op1, op2);
case BASE_FLOAT:
return new Float (op1.floatValue()/op2.floatValue());
case BASE_DOUBLE:
return new Double (op1.doubleValue()/op2.doubleValue());
// Default is BigDecimal operation
default:
return toBigDecimal( op1 ).divide( toBigDecimal( op2 ), BigDecimal.ROUND_HALF_DOWN);
}
}
/**
* Modulo two numbers.
* @param op1
* @param op2
* @return Modulo result.
*
* @throws ArithmeticException If at least one parameter is a BigDecimal
*/
public static Number modulo (Number op1, Number op2) throws ArithmeticException {
int calcBase = findCalculationBase( op1, op2);
switch (calcBase) {
case BASE_BIGINTEGER:
return toBigInteger( op1 ).mod( toBigInteger( op2 ));
case BASE_LONG:
return wrapPrimitive( op1.longValue() % op2.longValue(), op1, op2);
case BASE_FLOAT:
return new Float (op1.floatValue() % op2.floatValue());
case BASE_DOUBLE:
return new Double (op1.doubleValue() % op2.doubleValue());
// Default is BigDecimal operation
default:
throw new ArithmeticException( "Cannot calculate the modulo of BigDecimals.");
}
}
/**
* Compare two numbers.
* @param op1
* @param op2
* @return 1 if n1 > n2, -1 if n1 < n2 and 0 if equal.
*/
public static int compare (Number op1, Number op2) {
int calcBase = findCalculationBase( op1, op2);
switch (calcBase) {
case BASE_BIGINTEGER:
return toBigInteger( op1 ).compareTo( toBigInteger( op2 ));
case BASE_LONG:
long l1 = op1.longValue();
long l2 = op2.longValue();
if (l1 < l2) {
return -1;
}
if (l1 > l2) {
return 1;
}
return 0;
case BASE_FLOAT:
float f1 = op1.floatValue();
float f2 = op2.floatValue();
if (f1 < f2) {
return -1;
}
if (f1 > f2) {
return 1;
}
return 0;
case BASE_DOUBLE:
double d1 = op1.doubleValue();
double d2 = op2.doubleValue();
if (d1 < d2) {
return -1;
}
if (d1 > d2) {
return 1;
}
return 0;
// Default is BigDecimal operation
default:
return toBigDecimal( op1 ).compareTo( toBigDecimal ( op2 ));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -