本文共 3499 字,大约阅读时间需要 11 分钟。
在Java中,计算会出现失精度的情况:
一般情况下可以使用BigDecimal进行精确计算,但是如果需要进行复杂公式的计算,就比较麻烦了,我这里通过引用js脚本引擎来实现java的精确计算。 下面这个工具类提供了两个精确计算方法: 1.analyticalMathematicalFormula(String formula)上传的字符串公式中必须对应具体数值,才能精确计算出结果。package com.xj;/** * @program:Java_ssw * @description: * @author:尚龙龙 * @create:2021-06-28-16:49 **/public class Demo { public static void main(String[] args) { double num = (double)AccurateCalculationTools.analyticalMathematicalFormula("(1 + 1) * 8 / (86000) - 1"); System.out.println("结果:" + num); }}
结果:-0.9998139534883721
2.analyticalMathematicalFormula(String rule, Map<String, Object> maps)推荐使用,当计算公式的数值为动态时使用
package com.xj;/** * @program:Java_ssw * @description: * @author:尚龙龙 * @create:2021-06-28-16:49 **/public class Demo { public static void main(String[] args) { Mapmap = new HashMap (); map.put("A",1); map.put("B",1); map.put("C",8); map.put("D",86000); map.put("E",1); double num = (double)AccurateCalculationTools.analyticalMathematicalFormula("(A + B) * C / (D) - E",map); System.out.println("结果:" + num); }}
结果:-0.9998139534883721
工具类
package com.xj.utils;import javax.script.*;import java.util.*;import java.util.Map;/** * @program:Java_trs * @description:精确计算工具类 * @author:尚龙龙 * @create:2021-05-27-09:19 **/public class AccurateCalculationTools { public static Object analyticalMathematicalFormula(String formula) { //替换中英文括号 formula = formula.replace("(", "("); formula = formula.replace(")", ")"); Object result = formula; ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); try { result = engine.eval(formula);// } catch (ScriptException e) { return result; } return result; } public static Object analyticalMathematicalFormula(String rule, Mapmaps) { rule = rule.replace(" ", ""); //规则// String rule = "score1/score2"; //计算参数// String[] params = {"score1", "score2"}; //实体类// Map map = new HashMap();// map.put("score1", 1.0);// map.put("score2", 86400.0);// Contents contents = new HeaderFooter.Contents();// contents.setScore1(1);// contents.setScore2(2);// contents.setScore3(3); //对象转json// JSONObject jsonObj = JSONObject.fromObject(contents); // //ScriptEngineManager manager = new ScriptEngineManager(); //通过文件扩展名获取脚本引擎 ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); //将参数和实体类中的值 封装到hash中 Map paramValues = new HashMap (); for (Map.Entry entry : maps.entrySet()) { String param = entry.getKey(); double value = (double)entry.getValue(); paramValues.put(param, value); }// for (String param : map.entrySet()) { // paramValues.put(param, JsonUtils.getParamValue(jsonObj, param));// } //将hash转成集合 便于循环遍历 Iterator keys = paramValues.keySet().iterator(); //将key和value 封装到脚本引擎中 while (keys.hasNext()) { String key = keys.next(); if (engine.get(key) == null) { engine.put(key, paramValues.get(key)); } } //脚本引擎通过rule的计算公式 计算结果 Object calcValue = null; try { calcValue = engine.eval(rule); } catch (ScriptException e) { } return calcValue; }}
转载地址:http://wclsi.baihongyu.com/