22
33import cn .superiormc .ultimateshop .managers .ConfigManager ;
44import cn .superiormc .ultimateshop .managers .ErrorManager ;
5+ import com .ezylang .evalex .EvaluationException ;
56import com .ezylang .evalex .Expression ;
7+ import com .ezylang .evalex .config .ExpressionConfiguration ;
8+ import com .ezylang .evalex .data .EvaluationValue ;
9+ import com .ezylang .evalex .functions .AbstractFunction ;
10+ import com .ezylang .evalex .functions .FunctionParameter ;
11+ import com .ezylang .evalex .parser .Token ;
612
713import java .math .BigDecimal ;
814import java .math .RoundingMode ;
@@ -18,13 +24,21 @@ public class MathUtil {
1824
1925 public static DecimalFormat decimalFormat ;
2026
27+ private static ExpressionConfiguration expressionConfig ;
28+
29+ private static final int SIGMA_MAX_ITERATIONS = 100000 ;
30+
2131 public static void init () {
22- scale = ConfigManager .configManager .getInt ("math.scale" , 2 );
32+ scale = ConfigManager .configManager .getInt ("math.scale" , 2 );
2333 String integerPattern = ConfigManager .configManager .getString ("number-display.format.integer" , "#,##0" );
2434 String decimalPattern = ConfigManager .configManager .getString ("number-display.format.decimal" , "#,##0.00##########" );
2535 DecimalFormatSymbols symbols = DecimalFormatSymbols .getInstance (Locale .US );
2636 integerFormat = new DecimalFormat (integerPattern , symbols );
2737 decimalFormat = new DecimalFormat (decimalPattern , symbols );
38+
39+ expressionConfig = ExpressionConfiguration .builder ()
40+ .function ("SIGMA" , new SigmaFunction ())
41+ .build ();
2842 }
2943
3044 public static double multiply (double left , double right ) {
@@ -57,9 +71,10 @@ public static BigDecimal doCalculate(String mathStr, int scale) {
5771 if (!ConfigManager .configManager .getBoolean ("math.enabled" )) {
5872 return new BigDecimal (mathStr );
5973 }
60- return new Expression (mathStr ).evaluate ().getNumberValue ().setScale (scale , RoundingMode .HALF_UP );
61- }
62- catch (Throwable throwable ) {
74+ return new Expression (mathStr , expressionConfig ).evaluate ()
75+ .getNumberValue ()
76+ .setScale (scale , RoundingMode .HALF_UP );
77+ } catch (Throwable throwable ) {
6378 if (ConfigManager .configManager .getBoolean ("debug" )) {
6479 throwable .printStackTrace ();
6580 }
@@ -69,4 +84,36 @@ public static BigDecimal doCalculate(String mathStr, int scale) {
6984 return BigDecimal .ZERO ;
7085 }
7186 }
87+
88+ @ FunctionParameter (name = "start" )
89+ @ FunctionParameter (name = "end" )
90+ @ FunctionParameter (name = "body" )
91+ public static class SigmaFunction extends AbstractFunction {
92+
93+ @ Override
94+ public EvaluationValue evaluate (EvaluationValue ... args ) {
95+ int start = args [0 ].getNumberValue ().intValue ();
96+ int end = args [1 ].getNumberValue ().intValue ();
97+ String body = args [2 ].getStringValue ();
98+
99+ if (start > end ) {
100+ return EvaluationValue .numberValue (BigDecimal .ZERO );
101+ }
102+
103+ int count = end - start + 1 ;
104+ if (count > SIGMA_MAX_ITERATIONS ) {
105+ throw new EvaluationException (
106+ new Token (0 , body ),
107+ "SIGMA: too many iterations (" + count + "), maximum is " + SIGMA_MAX_ITERATIONS );
108+ }
109+
110+ BigDecimal sum = BigDecimal .ZERO ;
111+ for (int i = start ; i <= end ; i ++) {
112+ Expression subExpr = new Expression (body , expressionConfig )
113+ .with ("i" , BigDecimal .valueOf (i ));
114+ sum = sum .add (subExpr .evaluate ().getNumberValue ());
115+ }
116+ return EvaluationValue .numberValue (sum );
117+ }
118+ }
72119}
0 commit comments