该工具类提供了精确的金额计算方法,针对如除法等可能出现的精度问题使用BigDecimal实现精确计算。
public class NumberUtils {
private static final int DEF_DIV_SCALE = 10;
public static int getInt(String s) {
try {
return Integer.parseInt(s);
} catch (Exception e) {
return 0;
}
}
/**
* 提供精确的字符串转double
*/
public static double getDouble(String v) {
double value = 0.0;
try {
BigDecimal b = new BigDecimal(v);
value = b.doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
double value = 0.0;
try {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
value = b1.add(b2).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(String v1, String v2) {
double value = 0.0;
try {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
value = b1.add(b2).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的减法运算
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double substract(double v1, double v2) {
double value = 0.0;
try {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
value = b1.subtract(b2).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的减法运算
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double substract(String v1, String v2) {
double value = 0.0;
try {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
value = b1.subtract(b2).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double multiply(double v1, double v2) {
double value = 0.0;
try {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
value = b1.multiply(b2).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double multiply(String v1, String v2) {
double value = 0.0;
try {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
value = b1.multiply(b2).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,
* 精确到小数点以后10位以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double divide(double v1, double v2) {
return divide(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算
* 当发生除不尽的情况时,由scale参数决定精确小数点以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示要精确到小数点以后几位
* @return 两个参数的商
*/
public static double divide(double v1, double v2, int scale) {
double value = 0.0;
try {
if (scale < 0) {
return value;
//throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
value = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的小数位四舍五入处理
*
* @param v 原四舍五入的数
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
double value = 0.0;
try {
if (scale < 0) {
return value;
// throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
value = b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
return value;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
/**
* 提供精确的小数位四舍五入处理 默认2
*
* @return 四舍五入后的结果
*/
public static double round(double v) {
try {
return round(v, 2);
} catch (Exception e) {
return v;
}
}
/**
* 搜索出输入值最接近的范围内的某一个值
*
* @param key 输入的值
* @param arr 值范围
* @return 搜索到的索引
*/
public static double searchNearValue(double key, Double[] arr) {
// double[] arr = {1.78, 2.0, 2.08, 2.17}; 1920*1080;2160*1080;2250*1080;2340*1080
// double key = 1.82;
int search = Arrays.binarySearch(arr, key);
double searchKey = 0.0;
int index = 0;
if (search > 0 && search < arr.length) {
searchKey = arr[search];
index = search;
} else if (search == -1) {
searchKey = arr[0];
index = 0;
} else if (search == -(arr.length + 1)) {
searchKey = arr[arr.length - 1];
index = arr.length - 1;
} else if (search < 0 && search >= -arr.length) {
index = (-2 + Math.abs(search)) > 0 ? (-2 + Math.abs(search)) : 0;
searchKey = arr[index];
} else {
searchKey = arr[0];
index = 0;
}
double needValue = 0.0;
int nearIndex = 0;
if (index == arr.length - 1) {
needValue = arr[arr.length - 1];
nearIndex = arr.length - 1;
} else {
double min = arr[index];
double max = arr[index + 1];
if ((key - min) > (max - key)) {
needValue = max;
nearIndex = index + 1;
} else {
needValue = min;
nearIndex = index;
}
}
return needValue;
}
public static String reserve2Decimals(double d) {
java.text.DecimalFormat myformat = new java.text.DecimalFormat("0.00");
return myformat.format(d);
}
}