数据类型为BigDecimal,涉及到金额计算最好用BigDecimal.
package com.nantian.iwap.app.util;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 公式运算
* */
public class SZYSUtils {
private static BigDecimal BigDecimalCal(BigDecimal a1, BigDecimal a2, char operator) throws Exception {
switch (operator) {
case '+':
return a1.add(a2);
//return a1 + a2;
case '-':
return a1.subtract(a2);
//return a1 - a2;
case '*':
return a1.multiply(a2);
//return a1 * a2;
case '/':
return a1.divide(a2,20,BigDecimal.ROUND_HALF_UP);
//return a1 / a2;
default:
break;
}
throw new Exception("illegal operator!");
}
private static int getPriority(String s) throws Exception {
if(s==null) return 0;
else if(s.equals("(")) return 1;
else if(s.equals("+") || s.equals("-")) return 2;
else if(s.equals("*") || s.equals("/")) return 3;
/*
switch(s) {
case "(":return 1;
case "+":;
case "-":return 2;
case "*":;
case "/":return 3;
default:break;
}
*/
throw new Exception("illegal operator!");
}
public static String getResult(String expr) throws Exception {
// System.out.println("计算"+expr);
/*数字栈*/
Stack<BigDecimal> number = new Stack<BigDecimal>();
/*符号栈*/
Stack<String> operator = new Stack<String>();
operator.push(null);// 在栈顶压人一个null,配合它的优先级,目的是减少下面程序的判断
/* 将expr打散为运算数和运算符 */
Pattern p = Pattern.compile("(?);// 这个正则为匹配表达式中的数字或运算符
Matcher m = p.matcher(expr);
while(m.find()) {
String temp = m.group();
if(temp.matches("[+\\-*/()]")) {//遇到符号
if(temp.equals("(")) {//遇到左括号,直接入符号栈
operator.push(temp);
//System.out.println("符号栈更新:"+operator);
}else if(temp.equals(")")){//遇到右括号,"符号栈弹栈取栈顶符号b,数字栈弹栈取栈顶数字a1,数字栈弹栈取栈顶数字a2,计算a2 b a1 ,将结果压入数字栈",重复引号步骤至取栈顶为左括号,将左括号弹出
String b = null;
while(!(b = operator.pop()).equals("(")) {
// System.out.println("符号栈更新:"+operator);
BigDecimal a1 = number.pop();
BigDecimal a2 = number.pop();
// System.out.println("数字栈更新:"+number);
// System.out.println("计算"+a2+b+a1);
number.push(BigDecimalCal(a2, a1, b.charAt(0)));
// System.out.println("数字栈更新:"+number);
}
//System.out.println("符号栈更新:"+operator);
}else {//遇到运算符,满足该运算符的优先级大于栈顶元素的优先级压栈;否则计算后压栈
while(getPriority(temp) <= getPriority(operator.peek())) {
BigDecimal a1 = number.pop();
BigDecimal a2 = number.pop();
String b = operator.pop();
// System.out.println("符号栈更新:"+operator);
// System.out.println("数字栈更新:"+number);
// System.out.println("计算"+a2+b+a1);
number.push(BigDecimalCal(a2, a1, b.charAt(0)));
// System.out.println("数字栈更新:"+number);
}
operator.push(temp);
// System.out.println("符号栈更新:"+operator);
}
}else {//遇到数字,直接压入数字栈
number.push(new BigDecimal(temp));
// System.out.println("数字栈更新:"+number);
}
}
while(operator.peek()!=null) {//遍历结束后,符号栈数字栈依次弹栈计算,并将结果压入数字栈
BigDecimal a1 = number.pop();
BigDecimal a2 = number.pop();
String b = operator.pop();
// System.out.println("符号栈更新:"+operator);
// System.out.println("数字栈更新:"+number);
// System.out.println("计算"+a2+b+a1);
number.push(BigDecimalCal(a2, a1, b.charAt(0)));
// System.out.println("数字栈更新:"+number);
}
//System.out.println("值="+number.pop()+"");
BigDecimal pop = number.pop().setScale(2,BigDecimal.ROUND_HALF_UP);//科学计数,保留2位小数
// System.out.println(pop.toPlainString());
return pop.toPlainString();//数值完全显示
/*
NumberFormat nf = NumberFormat.getInstance();
nf.setGroupingUsed(false);
String format = nf.format(pop);//科学计数转换成完全显示
return format;
*/
// return number.pop()+"";
}
@SuppressWarnings("null")
public static void main(String[] args) throws Exception {
// String str = "0.000000001";
// str="0.0000001/10000000000";
// System.out.println(getResult(str));
String str="1.001";
BigDecimal a=new BigDecimal(str);
System.out.println(a.toPlainString());
Double b=Double.valueOf("1.001");
BigDecimal bb=new BigDecimal(Double.toString(b));
System.out.println(bb.toPlainString());
BigDecimal cc=new BigDecimal(Double.toString(b));
System.out.println(cc.toPlainString());
Double d=10000.994;
DecimalFormat df = new DecimalFormat("#,###.00");
System.out.println(df.format(d));
BigDecimal bb1=new BigDecimal("2000000.00");
BigDecimal bb2=new BigDecimal("1999999.999");
BigDecimal subtract = bb2.subtract(bb1);
System.out.println(subtract.toPlainString());
if( subtract.compareTo(BigDecimal.ZERO)==-1){//小于
System.out.println("负");
}else if( subtract.compareTo(BigDecimal.ZERO)==1){//大于
System.out.println("正");
}else{//==0等于
System.out.println("0");
}
Double valueOf = Double.valueOf(1999999.999-2000000.00);
System.out.println(BigDecimal.valueOf(valueOf).toPlainString());
BigDecimal decimalD=BigDecimal.valueOf(10000.99);
System.out.println(BigDecimal.valueOf(10000.99).toPlainString());
System.out.println(decimalD.toPlainString());
System.out.println(df.format(decimalD));
Double valueOf2 = Double.valueOf("10000000.999");
BigDecimal de=BigDecimal.valueOf(valueOf2);
System.out.println(de.toPlainString());
BigDecimal de2 = new BigDecimal(Double.toString(valueOf2));
System.out.println(de2.toPlainString());
BigDecimal de3 = new BigDecimal(valueOf2);
System.out.println(de3.toPlainString());
System.out.println(de.doubleValue());
BigDecimal v=new BigDecimal("-0.1");
if( v.compareTo(BigDecimal.ZERO)==-1){//小于
System.out.println("负");
}else if( v.compareTo(BigDecimal.ZERO)==1){//大于
System.out.println("正");
}else{//==0等于
System.out.println("0");
}
String aa=" 123 456 ";
String trim = aa.trim();
System.out.println(trim);
String ab=null;
String trim2 = ab.trim();//报空指针异常
System.out.println(trim2);
}
}
数据类型为double,会有精度丢失
package com.nantian.iwap.app.util;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 公式运算
* */
public class SZYSUtils_1 {
private static double doubleCal(double a1, double a2, char operator) throws Exception {
switch (operator) {
case '+':
return a1 + a2;
case '-':
return a1 - a2;
case '*':
return a1 * a2;
case '/':
return a1 / a2;
default:
break;
}
throw new Exception("illegal operator!");
}
private static int getPriority(String s) throws Exception {
if(s==null) return 0;
else if(s.equals("(")) return 1;
else if(s.equals("+") || s.equals("-")) return 2;
else if(s.equals("*") || s.equals("/")) return 3;
/*
switch(s) {
case "(":return 1;
case "+":;
case "-":return 2;
case "*":;
case "/":return 3;
default:break;
}
*/
throw new Exception("illegal operator!");
}
public static String getResult(String expr) throws Exception {
System.out.println("计算"+expr);
/*数字栈*/
Stack<Double> number = new Stack<Double>();
/*符号栈*/
Stack<String> operator = new Stack<String>();
operator.push(null);// 在栈顶压人一个null,配合它的优先级,目的是减少下面程序的判断
/* 将expr打散为运算数和运算符 */
Pattern p = Pattern.compile("(?);// 这个正则为匹配表达式中的数字或运算符
Matcher m = p.matcher(expr);
while(m.find()) {
String temp = m.group();
if(temp.matches("[+\\-*/()]")) {//遇到符号
if(temp.equals("(")) {//遇到左括号,直接入符号栈
operator.push(temp);
//System.out.println("符号栈更新:"+operator);
}else if(temp.equals(")")){//遇到右括号,"符号栈弹栈取栈顶符号b,数字栈弹栈取栈顶数字a1,数字栈弹栈取栈顶数字a2,计算a2 b a1 ,将结果压入数字栈",重复引号步骤至取栈顶为左括号,将左括号弹出
String b = null;
while(!(b = operator.pop()).equals("(")) {
//System.out.println("符号栈更新:"+operator);
double a1 = number.pop();
double a2 = number.pop();
// System.out.println("数字栈更新:"+number);
//System.out.println("计算"+a2+b+a1);
number.push(doubleCal(a2, a1, b.charAt(0)));
//System.out.println("数字栈更新:"+number);
}
//System.out.println("符号栈更新:"+operator);
}else {//遇到运算符,满足该运算符的优先级大于栈顶元素的优先级压栈;否则计算后压栈
while(getPriority(temp) <= getPriority(operator.peek())) {
double a1 = number.pop();
double a2 = number.pop();
String b = operator.pop();
//System.out.println("符号栈更新:"+operator);
//System.out.println("数字栈更新:"+number);
//System.out.println("计算"+a2+b+a1);
number.push(doubleCal(a2, a1, b.charAt(0)));
//System.out.println("数字栈更新:"+number);
}
operator.push(temp);
//System.out.println("符号栈更新:"+operator);
}
}else {//遇到数字,直接压入数字栈
number.push(Double.valueOf(temp));
//System.out.println("数字栈更新:"+number);
}
}
while(operator.peek()!=null) {//遍历结束后,符号栈数字栈依次弹栈计算,并将结果压入数字栈
double a1 = number.pop();
double a2 = number.pop();
String b = operator.pop();
//System.out.println("符号栈更新:"+operator);
//System.out.println("数字栈更新:"+number);
//System.out.println("计算"+a2+b+a1);
number.push(doubleCal(a2, a1, b.charAt(0)));
//System.out.println("数字栈更新:"+number);
}
// System.out.println("值="+number.pop()+"");
Double pop = number.pop();//科学计数
NumberFormat nf = NumberFormat.getInstance();
nf.setGroupingUsed(false);
String format = nf.format(pop);//科学计数转换成完全显示
return format;
// return number.pop()+"";
}
public static void main(String[] args) throws Exception {
String str = "-3.5*(4.5-(4+(-1-1/2)))";
str="(1.4-1)*3-5*(2.1-1)";
System.out.println(getResult(str));
}
}