package kernel.util;
|
|
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayOutputStream;
|
import java.io.DataInputStream;
|
import java.io.DataOutputStream;
|
import java.math.BigDecimal;
|
import java.math.BigInteger;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
import org.springframework.util.Assert;
|
|
/**
|
* 提供高精度的运算支持.
|
* 所以函数以double为参数类型,兼容int与float.
|
*
|
*/
|
public abstract class NumberUtils extends org.springframework.util.NumberUtils {
|
/**
|
* 精确的加法运算.
|
*/
|
public static double add(double v1, double v2) {
|
BigDecimal b1 = new BigDecimal(v1);
|
BigDecimal b2 = new BigDecimal(v2);
|
return b1.add(b2).doubleValue();
|
}
|
|
/**
|
*
|
* 精确的减法运算.
|
*
|
* @param v1 被减数
|
* @param v2 减数
|
*/
|
public static double subtract(double v1, double v2) {
|
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
return b1.subtract(b2).doubleValue();
|
}
|
|
/**
|
* 提供精确的乘法运算.
|
*/
|
public static double multiply(double v1, double v2) {
|
BigDecimal b1 = new BigDecimal(v1);
|
BigDecimal b2 = new BigDecimal(v2);
|
return b1.multiply(b2).doubleValue();
|
}
|
|
/**
|
* 提供精确的乘法运算,并对运算结果截位.
|
*
|
* @param scale 运算结果小数后精确的位数
|
*/
|
public static double multiply(double v1, double v2, int scale) {
|
if (scale < 0) {
|
throw new IllegalArgumentException("The scale must be a positive integer or zero");
|
}
|
BigDecimal b1 = new BigDecimal(v1);
|
BigDecimal b2 = new BigDecimal(v2);
|
return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
|
}
|
|
/**
|
* 提供(相对)精确的除法运算.
|
*
|
* @see #divide(double, double, int)
|
*/
|
public static double divide(double v1, double v2) {
|
BigDecimal b1 = new BigDecimal(v1);
|
BigDecimal b2 = new BigDecimal(v2);
|
return b1.divide(b2).doubleValue();
|
}
|
|
/**
|
* 提供(相对)精确的除法运算.
|
* 由scale参数指定精度,以后的数字四舍五入.
|
*
|
* @param v1 被除数
|
* @param v2 除数
|
* @param scale 表示表示需要精确到小数点以后几位
|
*/
|
public static double divide(double v1, double v2, int scale) {
|
if (scale < 0) {
|
throw new IllegalArgumentException("The scale must be a positive integer or zero");
|
}
|
|
BigDecimal b1 = new BigDecimal(v1);
|
BigDecimal b2 = new BigDecimal(v2);
|
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
|
}
|
|
/**
|
* 提供精确的小数位四舍五入处理.
|
*
|
* @param v 需要四舍五入的数字
|
* @param scale 小数点后保留几位
|
*/
|
public static double round(double v, int scale) {
|
if (scale < 0) {
|
throw new IllegalArgumentException("The scale must be a positive integer or zero");
|
}
|
BigDecimal b = new BigDecimal(v);
|
return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
|
}
|
|
public static int compare(Number left, Number right) throws IllegalArgumentException {
|
Assert.notNull(left, "left number must not be null");
|
Assert.notNull(right, "right number must not be null");
|
|
if (left.getClass().equals(Byte.class)) {
|
return ((Byte) left).compareTo((Byte) right);
|
}
|
else if (left.getClass().equals(Short.class)) {
|
return ((Short) left).compareTo((Short) right);
|
}
|
else if (left.getClass().equals(Integer.class)) {
|
return ((Integer) left).compareTo((Integer) right);
|
}
|
else if (left.getClass().equals(Long.class)) {
|
return ((Long) left).compareTo((Long) right);
|
}
|
else if (left.getClass().equals(BigInteger.class)) {
|
return ((BigInteger) left).compareTo((BigInteger) right);
|
}
|
else if (left.getClass().equals(Float.class)) {
|
return ((Float) left).compareTo((Float) right);
|
}
|
else if (left.getClass().equals(Double.class)) {
|
return ((Double) left).compareTo((Double) right);
|
}
|
else if (left.getClass().equals(BigDecimal.class)) {
|
return ((BigDecimal) left).compareTo((BigDecimal) right);
|
}
|
else {
|
throw new IllegalArgumentException("Could not compare left number [" + left + "] of type ["
|
+ left.getClass().getName() + "] to right number [" + right + "] of type ["
|
+ right.getClass().getName() + "]");
|
}
|
}
|
|
public static int safeLongToInt(long l) {
|
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
|
throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
|
}
|
return (int) l;
|
}
|
|
/**
|
* �����ָ�ʽ��Ϊ��Ǯ��ʽ
|
*
|
* @param number
|
* ���ʽ����BigDecimal
|
* @return С����2λ��ʽ���ַ�
|
*/
|
public static String formatNumericFee(BigDecimal number) {
|
return number.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
|
}
|
|
/**
|
* �����ָ�ʽ��Ϊ����ʽ
|
*
|
* @param number
|
* ���ʽ����BigDecimal
|
* @return С����6λ��ʽ���ַ�
|
*/
|
public static String formatNumericTraffic(BigDecimal number) {
|
return number.setScale(6, BigDecimal.ROUND_HALF_UP).toString();
|
}
|
|
// ���һ��ת����������bigdecimalת��ΪTB��GB��MB����ʽ
|
public static String mbToTGM(BigDecimal mb) {
|
StringBuffer sb = new StringBuffer(200);
|
int g = 0;
|
int t = 0;
|
BigDecimal m = new BigDecimal(0);
|
|
t = new Float(mb.divide(new BigDecimal(1024 * 1024), BigDecimal.ROUND_DOWN).floatValue()).intValue();
|
mb = mb.subtract((new BigDecimal(t).multiply(new BigDecimal(1024 * 1024))));
|
g = new Float(mb.divide(new BigDecimal(1024), BigDecimal.ROUND_DOWN).floatValue()).intValue();
|
mb = mb.subtract((new BigDecimal(g).multiply(new BigDecimal(1024))));
|
m = mb.setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
sb.append(new Integer(t).toString()).append(" TB ");
|
|
sb.append(new Integer(g).toString()).append(" GB ");
|
|
sb.append(m.toString()).append(" MB ");
|
|
return sb.toString();
|
}
|
|
// ��value��ǰ4���ֽڶs����һ�������
|
public static Integer readInt(byte[] value) {
|
if (value == null || value.length < 4) {
|
return null;
|
}
|
try {
|
ByteArrayInputStream bais = new ByteArrayInputStream(value);
|
DataInputStream dis = new DataInputStream(bais);
|
Integer retval = dis.readInt();
|
bais.close();
|
dis.close();
|
return retval;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
// ��value��ǰ}���ֽڶs����һ�������
|
public static Short readShort(byte[] value) {
|
if (value == null || value.length < 2) {
|
return null;
|
}
|
try {
|
ByteArrayInputStream bais = new ByteArrayInputStream(value);
|
DataInputStream dis = new DataInputStream(bais);
|
Short retval = dis.readShort();
|
bais.close();
|
dis.close();
|
return retval;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
public static byte[] intToByteArray(Integer value) {
|
if (value == null) {
|
return null;
|
}
|
|
try {
|
byte[] data = null;
|
ByteArrayOutputStream bais = new ByteArrayOutputStream(4);
|
DataOutputStream dos = new DataOutputStream(bais);
|
dos.writeInt(value);
|
data = bais.toByteArray();
|
bais.close();
|
dos.close();
|
return data;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
public static byte[] longToByteArray(long value) {
|
try {
|
byte[] data = null;
|
ByteArrayOutputStream bais = new ByteArrayOutputStream(8);
|
DataOutputStream dos = new DataOutputStream(bais);
|
dos.writeLong(value);
|
data = bais.toByteArray();
|
bais.close();
|
dos.close();
|
return data;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
public static Long readUnsingedInt(byte[] data, int offset) {
|
try {
|
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
|
dis.skip(offset);
|
Long retval = null;
|
int tmp = dis.readInt();
|
if (tmp < 0) {
|
retval = tmp + 4294967296L;
|
}
|
else {
|
retval = Long.valueOf(tmp);
|
}
|
|
dis.close();
|
return retval;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
public static boolean isNumeric(String str) {
|
Pattern pattern = Pattern.compile("[0-9]*");
|
Matcher isNum = pattern.matcher(str);
|
if (!isNum.matches()) {
|
return false;
|
}
|
return true;
|
}
|
}
|