Apache Commons JEXL 语法 https://ridikuius.github.io/Apache-Commons-JEXL3-%E8%AF%AD%E6%B3%95/
用这个实现类,避免算术溢出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package com.pandy.cpm.rule.service.impl; import org.apache.commons.jexl2.JexlArithmetic; import java.math.BigDecimal; import java.math.BigInteger; /*** * 修改过除法和求余数,当除0的时候得到Infinity这个结果 * @author Administrator * */ public class MyArithmetic extends JexlArithmetic { public MyArithmetic() { super(false); } protected double divideZero(BigDecimal x) { int ls = x.signum(); System.out.println(ls); if (ls < 0) { return Double.NEGATIVE_INFINITY; } else if (ls > 0) { return Double.POSITIVE_INFINITY; } else { return Double.NaN; } } protected double divideZero(BigInteger x) { int ls = x.signum(); System.out.println(ls); if (ls < 0) { return Double.NEGATIVE_INFINITY; } else if (ls > 0) { return Double.POSITIVE_INFINITY; } else { return Double.NaN; } } @Override public Object divide(Object left, Object right) { if (left == null && right == null) { return controlNullNullOperands(); } // if either are bigdecimal use that type if (left instanceof BigDecimal || right instanceof BigDecimal) { BigDecimal l = toBigDecimal(left); BigDecimal r = toBigDecimal(right); if (BigDecimal.ZERO.equals(r)) { return divideZero(l); } BigDecimal result = l.divide(r, getMathContext()); return narrowBigDecimal(left, right, result); } // if either are floating point (double or float) use double if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) { double l = toDouble(left); double r = toDouble(right); return new Double(l / r); } // otherwise treat as integers BigInteger l = toBigInteger(left); BigInteger r = toBigInteger(right); if (BigInteger.ZERO.equals(r)) { return divideZero(l); } BigInteger result = l.divide(r); return narrowBigInteger(left, right, result); } @Override public Object mod(Object left, Object right) { if (left == null && right == null) { return controlNullNullOperands(); } // if either are bigdecimal use that type if (left instanceof BigDecimal || right instanceof BigDecimal) { BigDecimal l = toBigDecimal(left); BigDecimal r = toBigDecimal(right); if (BigDecimal.ZERO.equals(r)) { return divideZero(l); } BigDecimal remainder = l.remainder(r, getMathContext()); return narrowBigDecimal(left, right, remainder); } // if either are floating point (double or float) use double if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) { double l = toDouble(left); double r = toDouble(right); return new Double(l % r); } // otherwise treat as integers BigInteger l = toBigInteger(left); BigInteger r = toBigInteger(right); BigInteger result = l.mod(r); if (BigInteger.ZERO.equals(r)) { return divideZero(l); } return narrowBigInteger(left, right, result); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.pandy.test; import org.apache.commons.jexl2.JexlArithmetic; import org.apache.commons.jexl2.JexlContext; import org.apache.commons.jexl2.JexlEngine; import org.apache.commons.jexl2.MapContext; public class JexlTest { public static void main(String[] args){ try { String jexlExp="1*2+6/(2+4)*1"; JexlEngine engine = new JexlEngine(null, new JexlArithmetic(true), null, null); JexlContext context = new MapContext(null); Object obj = engine.createExpression(jexlExp).evaluate(context); System.out.println(obj); } catch (Exception e) { e.printStackTrace(); } try { String jexlExp="(66)*1"; JexlEngine engine = new JexlEngine(null, new JexlArithmetic(true), null, null); JexlContext context = new MapContext(null); Object obj = engine.createExpression(jexlExp).evaluate(context); System.out.println(obj); } catch (Exception e) { e.printStackTrace(); } try { String jexlExp="66"; JexlEngine engine = new JexlEngine(null, new JexlArithmetic(true), null, null); JexlContext context = new MapContext(null); Object obj = engine.createExpression(jexlExp).evaluate(context); System.out.println(obj); } catch (Exception e) { e.printStackTrace(); } } } |