isPrecise
高精度计算在会计财务中非常重要,java的float、double、int、long存在很多隐式转换,
做四则运算和比较的时候其实存在非常多的安全隐患。 所以类似汇金的系统中,会有很多 BigDecimal
转换代码。
而使用QLExpress,你只要关注数学公式本身
订单总价 = 单价 * 数量 + 首重价格 + ( 总重量 - 首重) * 续重单价
然后设置这个属性即可,所有的中间运算过程都会保证不丢失精度。
备注:但是最后的数字格式好像无法指定?
测试案例
- 设置精度
/**
* 测试精度设置
* @throws Exception if any
*/
@Test
public void testPercise() throws Exception {
ExpressRunner runner = new ExpressRunner(true, false);
IExpressContext<String,Object> expressContext = new DefaultContext<>();
String expression ="12.3/3";
Object result = runner.execute(expression, expressContext, null, false, false);
System.out.println(result);
}
结果
4.1000000000
- 不设置精度
/**
* 测试非精度
* @throws Exception if any
*/
@Test
public void testNoPercise() throws Exception {
ExpressRunner runner = new ExpressRunner(false, false);
IExpressContext<String,Object> expressContext = new DefaultContext<>();
String expression ="12.3/3";
Object result = runner.execute(expression, expressContext, null, false, false);
System.out.println(result);
}
4.1000000000000005
isShortCircuit
在很多业务决策系统中,往往需要对布尔条件表达式进行分析输出,普通的java运算一般会通过逻辑短路来减少性能的消耗。
例如规则公式:
star>10000 and shoptype in('tmall','juhuasuan') and price between (100,900)
假设第一个条件 star>10000 不满足就停止运算。 但业务系统却还是希望把后面的逻辑都能够运算一遍,并且输出中间过程,保证更快更好的做出决策。
测试案例
- ShortcutTest.java
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* <p> 短路运算符测试 </p>
*
* <pre> Created: 2018/6/9 下午5:27 </pre>
* <pre> Project: tech-validation </pre>
*
* @author houbinbin
* @version 1.0
* @since JDK 1.7
*/
public class ShortcutTest {
private ExpressRunner runner = new ExpressRunner();
private void initial() throws Exception{
runner.addOperatorWithAlias("小于","<","$1 小于 $2 不满足期望");
runner.addOperatorWithAlias("大于",">","$1 大于 $2 不满足期望");
}
private boolean calculateLogicTest(String expression, IExpressContext<String, Object> expressContext, List<String> errorInfo) throws Exception {
return (Boolean)runner.execute(expression, expressContext, errorInfo, true, false);
}
/**
* 测试非短路逻辑,并且输出出错信息
* @throws Exception if any
*/
@Test
public void testShortCircuit() throws Exception {
runner.setShortCircuit(true);
IExpressContext<String,Object> expressContext = new DefaultContext<>();
expressContext.put("违规天数", 100);
expressContext.put("虚假交易扣分", 11);
expressContext.put("VIP", false);
List<String> errorInfo = new ArrayList<>();
initial();
String expression ="2 小于 1 and (违规天数 小于 90 or 虚假交易扣分 小于 12)";
boolean result = calculateLogicTest(expression, expressContext, errorInfo);
showErrorInfo(result, errorInfo);
}
/**
* 测试非短路逻辑,并且输出出错信息
* @throws Exception if any
*/
@Test
public void testNoShortCircuit() throws Exception {
runner.setShortCircuit(false);
IExpressContext<String,Object> expressContext = new DefaultContext<>();
expressContext.put("违规天数", 100);
expressContext.put("虚假交易扣分", 11);
expressContext.put("VIP", false);
List<String> errorInfo = new ArrayList<>();
initial();
String expression ="2 小于 1 and (违规天数 小于 90 or 虚假交易扣分 小于 12)";
boolean result = calculateLogicTest(expression, expressContext, errorInfo);
showErrorInfo(result, errorInfo);
}
/**
* 展现错误信息
* @param result 结果
* @param errorList 错误列表
*/
private void showErrorInfo(boolean result, List<String> errorList) {
if(result){
System.out.println("result is success!");
}else{
System.out.println("result is fail!");
for(String error : errorList){
System.out.println(error);
}
}
}
}
- testShortCircuit() 测试结果:
result is fail!
2 小于 1 不满足期望
- testNoShortCircuit() 测试结果:
result is fail!
2 小于 1 不满足期望
违规天数:100 小于 90 不满足期望