import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.security.auth.kerberos.KerberosKey; public class Main{ private static String multipleBigDecimal(String a,String b) { double a1=Double.parseDouble(a); double b1=Double.parseDouble(b); BigDecimal a2=BigDecimal.valueOf(a1); BigDecimal b2=BigDecimal.valueOf(b1); BigDecimal s=a2.multiply(b2); return s.toString(); } private static String divideBigDecimal(String a,String b) { double a1=Double.parseDouble(a); double b1=Double.parseDouble(b); BigDecimal a2=BigDecimal.valueOf(a1); BigDecimal b2=BigDecimal.valueOf(b1); BigDecimal s=a2.divide(b2,5,RoundingMode.HALF_UP);//当这里可能出现无限循环小数时,就必须指定保留位数 return s.toString(); } private static String addBigDecimal(String a,String b) { double a1=Double.parseDouble(a); double b1=Double.parseDouble(b); BigDecimal a2=BigDecimal.valueOf(a1); BigDecimal b2=BigDecimal.valueOf(b1); BigDecimal s=a2.add(b2); return s.toString(); } private static String substractBigDecimal(String a,String b) { double a1=Double.parseDouble(a); double b1=Double.parseDouble(b); BigDecimal a2=BigDecimal.valueOf(a1); BigDecimal b2=BigDecimal.valueOf(b1); BigDecimal s=a2.subtract(b2); return s.toString(); } //an example 9+3*3-6/2+3 private static String sizeyunsuan(String s) { //1、先将 +-*/找出来 int p=0;//the count of (+-*/) for(int i=0;i<s.length();i++) { if(s.charAt(i)=='+' || s.charAt(i)=='-' ||s.charAt(i)=='*' ||s.charAt(i)=='/') p++; } //将字符串按照运算符进行切割总共有 2*p+1个段 example:p=5 String[] piece=new String[2*p+1];// save pieces divided by operator 11 pieces int start=0,index=0;// for(int i=0;i<s.length();i++) { if(s.charAt(i)=='+' || s.charAt(i)=='-' ||s.charAt(i)=='*' ||s.charAt(i)=='/') { piece[index]=s.substring(start,i);//index=0 i=1 p[0]="9" index++; piece[index]=""+s.charAt(i); //index=1 i=1 p[1]="+" index++; start=i+1; //start=2 } } // last piece; piece[index]=s.substring(start,s.length()); /// int count=p; while(count>0) { // first calculate */ for(int i=0;i<piece.length;i++) { if(piece[i].equals("*") || piece[i].equals("/")) { //find strs in piece has not calculated //find strs left not equals "p" int l=0; for(l=i-1;l>-1;l--) { if(!piece[l].equals("p")) break; } //find strs right not equals "p" int r=0; for(r=i+1;r<piece.length;r++) { if(!piece[r].equals("p")) break; } if(piece[i].equals("*")) { piece[i]=multipleBigDecimal(piece[l], piece[r]); piece[l]="p"; piece[r]="p"; count--; } else { piece[i]=divideBigDecimal(piece[l], piece[r]); piece[l]="p"; piece[r]="p"; count--; } //break; } } //then calculate +- for(int i=0;i<piece.length;i++) { if(piece[i].equals("+") || piece[i].equals("-")) { //find strs in piece has not calculated //find strs left not equals "p" int l=0; for(l=i-1;l>-1;l--) { if(!piece[l].equals("p")) break; } //find strs right not equals "p" int r=0; for(r=i+1;r<piece.length;r++) { if(!piece[r].equals("p")) break; } if(piece[i].equals("+")) { piece[i]=addBigDecimal(piece[l], piece[r]); piece[l]="p"; piece[r]="p"; count--; } else { piece[i]=substractBigDecimal(piece[l], piece[r]); piece[l]="p"; piece[r]="p"; count--; } //break; } } } String r=""; //find the string not equals "p" for(int i=0;i<piece.length;i++) { if(!piece[i].equals("p")) { r=piece[i]; break; } } return r; } private static void calculate(String s) { while(true) { //find the innerest () int start=0,last=0; for(int i=0;i<s.length();i++) { if(s.charAt(i)=='(') start=i; if(s.charAt(i)==')') { last=i; break; } } if(last==0) { System.out.println("自定义方法"+sizeyunsuan(s)); return; } else { String s1=s.substring(0,start); String s2=s.substring(start+1,last); String s3=s.substring(last+1,s.length()); s=s1+sizeyunsuan(s2)+s3; } } } public static void main(String[] args) throws ScriptException{ String s="3.6+(1.4+2*32/(3-2.1))*2.3"; calculate(s); ScriptEngineManager manager=new ScriptEngineManager(); ScriptEngine engine=manager.getEngineByName("js"); Object result=engine.eval(s); System.out.println("脚本方法 类型"+result.getClass().getName()+" 值:"+result); } }
输出
自定义方法170.375553
脚本方法 类型java.lang.Double 值:170.37555555555556