相關文章:
java 數學計算工具
java 對數學計算的使用性上還是比較麻煩的,遇到大量數據計算複雜的計算公式則會頻發問題。接下來我們來統計一下在java中經常會遇到的計算問題
- 科學計數法
- 保留小數點問題
- 複雜公式處理麻煩
- 除數爲零
…
案例:
比如說我需要計算一下數據
案例1
100*2000/20*(20-10)
使用java原生BigDecimal來寫計算會非常痛苦,所以封裝了一套工具供大家使用
public void test(){
BigDecimal bigDecimal = new BigDecimal(100);
bigDecimal= bigDecimal.multiply(new BigDecimal(2000));
bigDecimal=bigDecimal.divide(new BigDecimal(20));
BigDecimal b2 = new BigDecimal(20);
BigDecimal b3 = new BigDecimal(10);
b2 = b2.subtract(b3);
bigDecimal = bigDecimal.multiply(b2);
System.out.println(bigDecimal.setScale(2).doubleValue());
}
使用MyMath 工具寫法
public void myMathTest(){
MyMath.test("%s*%s/%s*(%s-%s)","100","2000","20","20","10");
}
不論是代碼可讀性,和代碼量以及維護性功能都是大大提升的
MyMath 功能介紹
MyMath 自動會處理科學計算法,異常數據等。使用的是js計算
- 普通計算
String value1= MyMath.test("100*2000/20*(20-10)");
或者
String value= MyMath.test("%s*%s/%s*(%s-%s)","100","2000","20","20","10");
- 布爾計算
boolean b = MyMath.test2("10>=(5-1)");
或者
boolean b1 = MyMath.test2("%s>=(%s-%s)", "10", "5", "1");
- 得分計算
得分計算如果都不滿足條件則返回0分
String score = MyMath.getScore("Math.abs(%s-%s)<=10:10,Math.abs(%s-%s)<=15:5", "10", "20");
結果得10分
計算已,號做分割。從做往右依次計算。如果滿足條件則返回:後面的得分,如果一個都未滿足則返回0分
MyMath 核心代碼
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MyMath {
String[] str = {"NaN", "Infinity"};
static ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
/**
* 判斷
* (
*
* @param str 數學公式
* @return
*/
public static boolean test2(String str) {
str = str.replaceAll("null", "0");
try {
if (VerifyUtil.isEmpty(str)) return false;
str = str.replace("--", "+");
Object result = engine.eval(str);
if (result instanceof Boolean)
return (boolean) result;
} catch (ScriptException e) {
e.printStackTrace();
}
return false;
}
/**
* 判斷計算
*
* @param str 數學佔位符公式
* @param strs 替換數據
* @return
*/
public static boolean test2(String str, String... strs) {
str = String.format(str, strs);
return test2(str);
}
/**
* 累加
*
* @param baseNum
* @param num
* @return
*/
public static String append(String baseNum, String num) {
return MyMath.test(baseNum + "+" + getNumber(num));
}
/**
* 累加
*
* @param baseNum
* @param key
* @return
*/
public static String append(String baseNum, Map<String, Object> param, String key) {
if (VerifyUtil.isEmpty(param)) return "0";
return append(baseNum, getNumber(param.get(key)));
}
public static String getNumber(Object object) {
if (VerifyUtil.isEmpty(object)) return "0";
return object + "";
}
/**
* 判斷
*
* @param str 數學公式
* @return
*/
public static boolean isInt(String str) {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return false;
str = str.replace("--", "+");
Object result = null;
try {
result = engine.eval(str);
} catch (ScriptException e) {
e.printStackTrace();
return false;
}
if (result instanceof Boolean)
return (boolean) result;
return false;
}
/**
* 4位小數點
*
* @param str 數學公式
* @return
*/
public static String test(String str) {
return endMath(str, "###0.0000");
}
/**
* 計算得出結果
*
* @param str 佔位符公式
* @param strs 替換值
* @return
*/
public static String test(String str, String... strs) {
str = String.format(str, strs);
return test(str);
}
/**
* 轉換整數字符串,科學計算法也可以轉換
*
* @param str
* @return
*/
public static String tesInt(String str) {
return endMath(str, "###0");
}
/**
* 8位小數點
*
* @param str
* @return
*/
public static String end8(String str) {
return endMath(str, "###0.00000000");
}
/**
* 保留小數點計算
*
* @param str 佔位符公式
* @param toFixed 保留小數點數
* @param strs 替換值
* @return
*/
public static String test(String str, int toFixed, String... strs) {
str = String.format(str, strs);
return test(str, toFixed);
}
/**
* 拋出異常計算,用來定位做了什麼處理
*
* @param str 佔位符公式
* @param toFixed 保留小數位數
* @param strs 替換值
* @return
* @throws MathException 拋出異常,包含計算錯誤公式
*/
public static String testMathException(String str, int toFixed, String... strs) throws MathException {
str = String.format(str, strs);
return testException(str, toFixed);
}
/**
* 拋出異常計算,用來定位做了什麼處理
*
* @param str 計算公式
* @param toFixed 保留小數位
* @return
* @throws MathException
*/
public static String testException(String str, int toFixed) throws MathException {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return "0";
str = str.replace("--", "+");
Object result = 0;
try {
result = engine.eval(str);
DecimalFormat decimalFormat = new DecimalFormat("###0.0000");//格式化設置
result = decimalFormat.format(result);
if (isInteger(result + "")) {
BigDecimal bigDecimal = new BigDecimal(result + "");
result = bigDecimal.setScale(toFixed, BigDecimal.ROUND_HALF_UP).toPlainString();
}
} catch (ScriptException e) {
throw new MathException(str);
}
return isNumber(result + "");
}
/**
* 普通計算保留小數位
*
* @param str 計算公式
* @param toFixed 保留小數位
* @return
*/
public static String test(String str, int toFixed) {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return "0";
str = str.replace("--", "+");
Object result = 0;
try {
result = engine.eval(str);
DecimalFormat decimalFormat = new DecimalFormat("###0.0000");//格式化設置
result = decimalFormat.format(result);
if (isInteger(result + "")) {
BigDecimal bigDecimal = new BigDecimal(result + "");
result = bigDecimal.setScale(toFixed, BigDecimal.ROUND_HALF_UP).toPlainString();
}
} catch (ScriptException e) {
System.out.println("報錯公式==== " + str);
e.printStackTrace();
}
return isNumber(result + "");
}
/**
* 是否是數字
*
* @param num
* @return
*/
public static String isNumber(String num) {
if (isInteger(num)) {
if (MyMath.test2(num + "==0")) return "0";
return num;
}
return "0";
}
/**
* 判斷是否是計算數據類型
*
* @param obj
* @return
*/
public static boolean isInteger(Object obj) {
String str = obj + "";
return match("^(-)?[0-9]+(\\.[0-9]+)?$", str);
}
/**
* 是否有小數點
*
* @param str
* @return
*/
public static boolean isHavaFixed(String str) {
return str.contains(".");
}
/**
* @param regex 正則表達式字符串
* @param str 要匹配的字符串
* @return 如果str 符合 regex的正則表達式格式,返回true, 否則返回 false;
*/
public static boolean match(String regex, String str) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.matches();
}
/**
* 數據計算指定格式
*
* @param str 計算公式
* @param form 指定格式
* @return
*/
public static String endMath(String str, String form) {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return "0";
str = str.replace("--", "+");
Object result = 0;
try {
result = engine.eval(str);
DecimalFormat decimalFormat = new DecimalFormat(form);//防止科學計算
result = decimalFormat.format(result);
} catch (ScriptException e) {
System.out.println("報錯公式==== " + str);
e.printStackTrace();
}
return isNumber(result + "");
}
/**
* @param input
* @return 判斷是否是使用科學計數法的數字字符串
*/
public static boolean getScientific(String input) {
String regx = "^((-?\\d+.?\\d*)[Ee]{1}(-?\\d+))$";//科學計數法正則表達式
Pattern pattern = Pattern.compile(regx);
return pattern.matcher(input).matches();
}
/**
* 公式佔比
* ("Math.abs(%s-%s)<=10:10,Math.abs(%s-%s)<=15:5", "10","20");
*
* @param math
* @return
*/
public static String getScore(String math, String... values) {
String score = "0";
String[] split = math.split(",");
for (String s : split) {
String itemMath = String.format(s, values);
String[] split1 = itemMath.split(":");
if (MyMath.test2(split1[0])) {
score = split1[1];
return score;
}
}
return score;
}
/**
* 結果計算,帶權重
* ("Math.abs(%s-%s)<=10:10,Math.abs(%s-%s)<=15:5", 10, "10","20");
*
* @param math
* @return
*/
public static String getScore(String math, Object weight, String... values) {
String score = "0";
String[] split = math.split(",");
for (String s : split) {
String itemMath = String.format(s, values);
String[] split1 = itemMath.split(":");
if (MyMath.test2(split1[0])) {
score = split1[1];
score = MyMath.test(score + "*" + weight);
return score;
}
}
return score;
}
public static void main(String[] args) {
System.out.println(endMath("30021321321.332323", "#0.00"));
// System.out.println(test("(1+3)/10*10"));
// Double double1 = 123456789.123456789;
// Double double1 = 1.2345678912345679E8;
// DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");//格式化設置
// System.out.println(decimalFormat.format(double1));
// System.out.println(double1);
}
public static class MathException extends Exception {
String excMath;
public MathException() {
}
public MathException(String excMath) {
this.excMath = excMath;
}
public String getExcMath() {
return excMath;
}
public void setExcMath(String excMath) {
this.excMath = excMath;
}
}
}