import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class NewMathUtil {
private static final Logger logger = LoggerFactory.getLogger(NewMathUtil.class);
/**
* 自动解析字符串内容并计算,同时可设置保留小数点位数
*
* @param operatorStr 运算式,eg. 10/3 or 1*5 or 6+1 or 8-1
* @param xsdws 保留小数点位数
* @return
*/
public static String autoCalc(String operatorStr, int xsdws) {
char[] chars = "+-*/".toCharArray();
for (char tempC : chars) {
String operation = String.valueOf(tempC);
if (operatorStr.contains(operation)) {
return calcOperatorChar(operatorStr, xsdws);
}
}
return null;
}
/**
* 自动解析字符串内容并计算,同时可设置保留小数点位数
*
* @param operatorStr 运算式,eg. 10/3 or 1*5 or 6+1 or 8-1
* @param xsdws 保留小数点位数
* @param bigDecimalRule 小数点的取舍规则
* @return
*/
public static String autoCalc(String operatorStr, int xsdws, Integer bigDecimalRule) {
char[] chars = "+-*/".toCharArray();
for (char tempC : chars) {
String operation = String.valueOf(tempC);
if (operatorStr.contains(operation)) {
return calcOperatorChar(operatorStr, xsdws, bigDecimalRule);
}
}
return null;
}
/**
* 整数只保留整数,小数统一保留2位小数。
* eg. "100", "100.0", "100.00", "0", "0.0", "0.00", "0.1", "0.12", "3", "3.0", "3.1", "3.12", "3.345"
* --> 100, 100, 100, 0, 0, 0, 0.10, 0.12, 3, 3, 3.10, 3.12, 3.34
*
* @param rate
* @return
*/
public static String keep2DecimalPlacesExceptInteger(String rate) {
if (rate != null) {
if (rate.startsWith("100")) {// 100 or 100.0 100.00 --> 100
rate = "100";
} else if (rate.equals("0") || rate.equals("0.0") || rate.equals("0.00")) {// 0 or 0.0 or 0.00 --> 0
rate = "0";
} else if (rate.endsWith(".0") || rate.endsWith(".00")) {// 3.0 or 3.00 --> 3
rate = rate.split("\\.")[0];
} else if (rate.contains(".")) {
if (rate.split("\\.")[1].length() == 1) {// 3.1 --> 3.10
rate += "0";
} else if (rate.split("\\.")[1].length() > 1) {// 3.345 --> 3.34
rate = rate.split("\\.")[0] + "." + rate.split("\\.")[1].substring(0, 2);
}
} /*else if (!rate.contains(".")) {// 10 --> 10
//
}*/
}
return rate;
}
/**
* 功能:输入字符串的计算式得到指定位数的结果
*
* @param operator 计算式(如 10/3)
* @param ws 四舍五入,保留几位小数(默认保留2位小数)
* @param <T>
* @return
*/
public static <T> String calcOperatorChar(String operator, T ws) {
return method(operator, ws, BigDecimal.ROUND_HALF_UP);
}
public static <T> String calcOperatorChar(String operator, T xsdws, Integer bigDecimalRule) {
if (bigDecimalRule == null) {
// 小数点保留规则:默认"四舍五入"
bigDecimalRule = BigDecimal.ROUND_HALF_UP;
}
// ROUND_HALF_UP:四舍五入
// ROUND_HALF_DOWN:五舍六入
// ROUND_DOWN:直接删除多余的小数位
// ROUND_UP:进位处理
return method(operator, xsdws, bigDecimalRule);
}
private static <T> String method(String operator, T xsdNum, Integer roundRule) {
int xsdws = 0;
if (xsdNum == null) {// 默认保留2位小数
xsdws = 2;
} else if (xsdNum instanceof Integer) {
xsdws = (Integer) xsdNum;
} else if (xsdNum instanceof String) {
xsdws = Integer.parseInt((String) xsdNum);
} else {
throw new RuntimeException("ws 格式有误(只能为 String or Integer 类型)");
}
operator = operator.replaceAll(" ", "");
String[] split = operator.split("[+,-,*,/]");
if (split.length != 2 || (split.length == 2 && operator.length() - split[0].length() - split[1].length() != 1)) {
throw new RuntimeException("运算符非 +-*/ 中的一种 or 存在多个运算符 or 运算式有误");
}
String s1 = split[0];
String s2 = split[1];
BigDecimal bigDecimal = null;
if (operator.contains("+")) {
bigDecimal = new BigDecimal(s1).add(new BigDecimal(s2));
} else if (operator.contains("-")) {
bigDecimal = new BigDecimal(s1).subtract(new BigDecimal(s2));
} else if (operator.contains("*")) {
bigDecimal = new BigDecimal(s1).multiply(new BigDecimal(s2));
} else if (operator.contains("/")) {
bigDecimal = new BigDecimal(s1).divide(new BigDecimal(s2), xsdws, roundRule != null ? roundRule : BigDecimal.ROUND_HALF_UP);
} else {
throw new RuntimeException("operator not contains +-*/");
}
return keepXSD(xsdws, bigDecimal);
}
private static <T> String keepXSD(int xsdCount, T num) {
StringBuilder zwf = new StringBuilder().append("#0.");// 占位符
for (int i = 0; i < xsdCount; i++) {
zwf.append("0");
}
BigDecimal bigDecimal = null;
if (num instanceof String) {
bigDecimal = new BigDecimal((String) num);
} else if (num instanceof BigDecimal) {
bigDecimal = (BigDecimal) num;
} else if (num instanceof Long) {
bigDecimal = new BigDecimal((Long) num);
} else if (num instanceof Float) {
bigDecimal = new BigDecimal((Float) num);
} else if (num instanceof Double) {
bigDecimal = new BigDecimal((Double) num);
} else {
throw new RuntimeException("num 只支持 int、long、double、float、String 几种类型");
}
String format = new DecimalFormat(zwf.toString()).format(bigDecimal);
// .123 ==> 0.123
if (format.startsWith(".")) {
format = "0" + format;
}
// 10. ==> 10
if (format.endsWith(".")) {
format = format.substring(0, format.length() - 1);
}
return format;
}
}