Java使⽤BigDecimal精确计算的简单公式计算器由于⼯作需要,写了⼀个使⽤BigDecimal运算的精确计算的计算器(然后发现其实⽐不⽤BigDecimal的并好不到哪⾥去)
只能做加减乘除
double类型的数字在千万级别的时候会转成科学计数法,我这个不会(我估计能有⽅法不以科学计数法显⽰)
其中⽤到的知识就是中缀表达式转后缀表达式,我是从这⾥学的:
下⾯上代码吧:
这个⽅法需要⼀个参数,String类型公式,形如:"1+(2-3*4)/5";
这个⽅法⽤来对已经转换成后缀表达式的公式进⾏处理
public static BigDecimal getResult(String input){
//规范输⼊形式,避免⽤户输⼊中⽂括号
placeAll("(","(");
placeAll(")",")");
//对输⼊公式,按符号/数字,⽤空格分开,以便后⾯分组
String[] inputs=input.split("");
String format="";
for (int i=0;i<inputs.length;i++){
if (inputs[i].equals(" ")){
continue;
}else if (inputs[i].equals("(")||inputs[i].equals(")")||inputs[i].equals("+")||inputs[i].equals("-")||inputs[i].equals("*")||inputs[i].equals("/")){ format+=" "+inputs[i]+" ";
}else {
format+=inputs[i];
}
}
List<String> strings=changeInfixExpressionToPostfixExpression(format);
Stack<String> stack=new Stack<String>();
for (int i=0;i<strings.size();i++){
if ((i).equals("+")){
BigDecimal a=new BigDecimal(stack.pop());
BigDecimal b=new BigDecimal(stack.pop());
stack.add(b.add(a).toString());
}else if ((i).equals("-")){
BigDecimal a=new BigDecimal(stack.pop());
BigDecimal b=new BigDecimal(stack.pop());
stack.add(b.subtract(a).toString());
}else if ((i).equals("*")){
BigDecimal a=new BigDecimal(stack.pop());
BigDecimal b=new BigDecimal(stack.pop());
stack.add(b.multiply(a).toString());
}else if ((i).equals("/")){
BigDecimal a=new BigDecimal(stack.pop());
BigDecimal b=new BigDecimal(stack.pop());
//这⾥的1000是做除法以后计算的精确位数,就算1000位也并不会拖慢程序速度,⼀个公式0.01秒内就能算完,后⾯的是除不尽的四舍五⼊ stack.add(b.divide(a,1000,BigDecimal.ROUND_HALF_DOWN).toString());
}else {
stack.(i));
}
}
//返回的时候格式化⼀下,取四舍五⼊⼩数点后两位
return new BigDecimal(stack.pop()).setScale(2,BigDecimal.ROUND_HALF_DOWN);
}
这个⽅法呢,就是将输⼊的中缀表达式转成后缀表达式:
public static List changeInfixExpressionToPostfixExpression(String input){
List<String> resultList=new ArrayList<String>();
Stack<String> tempStack=new Stack<String>();
String[] splitArray=input.split(" ");
for (int i=0;i<splitArray.length;i++){
if (splitArray[i].equals("")){
continue;
}
//如果字符是右括号的话,说明前⾯⼀定有过左括号,将栈⾥第⼀个左括号之前全部添加到List⾥
if (splitArray[i].equals(")")){
while (!tempStack.peek().equals("(")){
bigdecimal除法保留小数resultList.add(tempStack.pop());
}
tempStack.pop();//去除前⾯的左括号
}else if (splitArray[i].equals("(")){
/
/如果是左括号,那么直接添加进去
tempStack.add("(");
}else if (splitArray[i].equals("+")||splitArray[i].equals("-")){
//如果是加减号,还需要再判断
if (pty()||tempStack.peek().equals("(")){
tempStack.add(splitArray[i]);
}else if (tempStack.peek().equals("+")||tempStack.peek().equals("-")){
//读临时栈⾥的顶部数据,如果也是加减就取出来⼀个到结果列,这个放临时栈,如果是乘除就开始取到右括号为⽌ resultList.add(tempStack.pop());
tempStack.add(splitArray[i]);
}else {
while (!pty()){
if (tempStack.peek().equals("(")){
break;
}else {
resultList.add(tempStack.pop());
}
}
tempStack.add(splitArray[i]);
}
}else if (splitArray[i].equals("*")||splitArray[i].equals("/")){
//如果是乘除
if (!pty()){
/
/判断临时栈⾥栈顶是啥,如果是乘除,取⼀个出来到结果列,添这个进临时栈
if (tempStack.peek().equals("*")||tempStack.peek().equals("/")){
resultList.add(tempStack.pop());
}
}
tempStack.add(splitArray[i]);
}else {
//说明是⾮符号,都添加进去
resultList.add(splitArray[i]);
}
}
/
/遍历完了,把临时stack⾥的东西都加到结果stack⾥去
while (!pty()){
resultList.add(tempStack.pop());
}
return resultList;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论