Browse Source

add BigDecimal scale and rounding config

James 5 years ago
parent
commit
cf791ec9a2
1 changed files with 25 additions and 3 deletions
  1. 25 3
      src/main/java/com/jfinal/template/expr/ast/Arith.java

+ 25 - 3
src/main/java/com/jfinal/template/expr/ast/Arith.java

@@ -18,6 +18,7 @@ package com.jfinal.template.expr.ast;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.util.Objects;
 import com.jfinal.template.TemplateException;
 import com.jfinal.template.expr.Sym;
 import com.jfinal.template.stat.Location;
@@ -41,6 +42,26 @@ public class Arith extends Expr {
 	private Expr left;
 	private Expr right;
 	
+	// BigDecimal 除法使用的最小 scale 值,默认为 5
+	protected static int bigDecimalDivideMinScale = 5;
+	// BigDecimal 除法使用的舍入模式,默认为四舍五入
+	protected static RoundingMode bigDecimalDivideRoundingMode = RoundingMode.HALF_UP;
+	
+	/**
+	 * 设置 BigDecimal 除法使用的最小 scale 值,默认为 5
+	 */
+	public static void setBigDecimalDivideMinScale(int bigDecimalDivideMinScale) {
+		Arith.bigDecimalDivideMinScale = bigDecimalDivideMinScale;
+	}
+	
+	/**
+	 * 设置 BigDecimal 除法使用的舍入模式,默认为四舍五入
+	 */
+	public static void setBigDecimalDivideRoundingMode(RoundingMode roundingMode) {
+		Objects.requireNonNull(roundingMode, "roundingMode can not be null");
+		Arith.bigDecimalDivideRoundingMode = roundingMode;
+	}
+	
 	public Arith(Sym op, Expr left, Expr right, Location location) {
 		if (left == null || right == null) {
 			throw new ParseException("The target of \"" + op.value() + "\" operator can not be blank", location);
@@ -80,7 +101,7 @@ public class Arith extends Expr {
 			case DIV:
 				return div(maxType, l, r);
 			case MOD:
-				return mod(maxType, l, r);
+				return remainder(maxType, l, r);
 			default :
 				throw new TemplateException("Unsupported operator: " + op.value(), location);
 			}
@@ -201,12 +222,13 @@ public class Arith extends Expr {
 		case BIGDECIMAL:
 			BigDecimal[] bd = toBigDecimals(left, right);
 			// return (bd[0]).divide(bd[1]);
-			return (bd[0]).divide(bd[1], RoundingMode.HALF_EVEN);	// 银行家舍入法
+			int scale = Math.max(bigDecimalDivideMinScale, bd[0].scale());
+			return (bd[0]).divide(bd[1], scale, bigDecimalDivideRoundingMode);
 		}
 		throw new TemplateException("Unsupported data type", location);
 	}
 	
-	private Number mod(int maxType, Number left, Number right) {
+	private Number remainder(int maxType, Number left, Number right) {
 		switch (maxType) {
 		case INT:
 			return Integer.valueOf(left.intValue() % right.intValue());