由于工作需要,写了一个使用BigDecimal运算的精确计算的计算器(然后发现其实比不用BigDecimal的并好不到哪里去)

只能做加减乘除

double类型的数字在千万级别的时候会转成科学计数法,我这个不会(我估计能有方法不以科学计数法显示)

其中用到的知识就是中缀表达式转后缀表达式,我是从这里学的:

http://www.cnblogs.com/mygmh/archive/2012/10/06/2713362.html

下面上代码吧:

这个方法需要一个参数,String类型公式,形如:"1+(2-3*4)/5";
这个方法用来对已经转换成后缀表达式的公式进行处理

  1. public static BigDecimal getResult(String input){
  2. //规范输入形式,避免用户输入中文括号
  3. input=input.replaceAll("(","(");
  4. input=input.replaceAll(")",")");
  5. //对输入公式,按符号/数字,用空格分开,以便后面分组
  6. String[] inputs=input.split("");
  7. String format="";
  8. for (int i=0;i<inputs.length;i++){
  9. if (inputs[i].equals(" ")){
  10. continue;
  11. }else if (inputs[i].equals("(")||inputs[i].equals(")")||inputs[i].equals("+")||inputs[i].equals("-")||inputs[i].equals("*")||inputs[i].equals("/")){
  12. format+=" "+inputs[i]+" ";
  13. }else {
  14. format+=inputs[i];
  15. }
  16. }
  17. List<String> strings=changeInfixExpressionToPostfixExpression(format);
  18. Stack<String> stack=new Stack<String>();
  19. for (int i=0;i<strings.size();i++){
  20. if (strings.get(i).equals("+")){
  21. BigDecimal a=new BigDecimal(stack.pop());
  22. BigDecimal b=new BigDecimal(stack.pop());
  23. stack.add(b.add(a).toString());
  24. }else if (strings.get(i).equals("-")){
  25. BigDecimal a=new BigDecimal(stack.pop());
  26. BigDecimal b=new BigDecimal(stack.pop());
  27. stack.add(b.subtract(a).toString());
  28. }else if (strings.get(i).equals("*")){
  29. BigDecimal a=new BigDecimal(stack.pop());
  30. BigDecimal b=new BigDecimal(stack.pop());
  31. stack.add(b.multiply(a).toString());
  32. }else if (strings.get(i).equals("/")){
  33. BigDecimal a=new BigDecimal(stack.pop());
  34. BigDecimal b=new BigDecimal(stack.pop());
  35. //这里的1000是做除法以后计算的精确位数,就算1000位也并不会拖慢程序速度,一个公式0.01秒内就能算完,后面的是除不尽的四舍五入
  36. stack.add(b.divide(a,1000,BigDecimal.ROUND_HALF_DOWN).toString());
  37. }else {
  38. stack.add(strings.get(i));
  39. }
  40. }
  41. //返回的时候格式化一下,取四舍五入小数点后两位
  42. return new BigDecimal(stack.pop()).setScale(2,BigDecimal.ROUND_HALF_DOWN);
  43. }

这个方法呢,就是将输入的中缀表达式转成后缀表达式:

  1. public static List changeInfixExpressionToPostfixExpression(String input){
  2. List<String> resultList=new ArrayList<String>();
  3. Stack<String> tempStack=new Stack<String>();
  4. String[] splitArray=input.split(" ");
  5. for (int i=0;i<splitArray.length;i++){
  6. if (splitArray[i].equals("")){
  7. continue;
  8. }
  9. //如果字符是右括号的话,说明前面一定有过左括号,将栈里第一个左括号之前全部添加到List里
  10. if (splitArray[i].equals(")")){
  11. while (!tempStack.peek().equals("(")){
  12. resultList.add(tempStack.pop());
  13. }
  14. tempStack.pop();//去除前面的左括号
  15. }else if (splitArray[i].equals("(")){
  16. //如果是左括号,那么直接添加进去
  17. tempStack.add("(");
  18. }else if (splitArray[i].equals("+")||splitArray[i].equals("-")){
  19. //如果是加减号,还需要再判断
  20. if (tempStack.empty()||tempStack.peek().equals("(")){
  21. tempStack.add(splitArray[i]);
  22. }else if (tempStack.peek().equals("+")||tempStack.peek().equals("-")){
  23. //读临时栈里的顶部数据,如果也是加减就取出来一个到结果列,这个放临时栈,如果是乘除就开始取到右括号为止
  24. resultList.add(tempStack.pop());
  25. tempStack.add(splitArray[i]);
  26. }else {
  27. while (!tempStack.empty()){
  28. if (tempStack.peek().equals("(")){
  29. break;
  30. }else {
  31. resultList.add(tempStack.pop());
  32. }
  33. }
  34. tempStack.add(splitArray[i]);
  35. }
  36. }else if (splitArray[i].equals("*")||splitArray[i].equals("/")){
  37. //如果是乘除
  38. if (!tempStack.empty()){
  39. //判断临时栈里栈顶是啥,如果是乘除,取一个出来到结果列,添这个进临时栈
  40. if (tempStack.peek().equals("*")||tempStack.peek().equals("/")){
  41. resultList.add(tempStack.pop());
  42. }
  43. }
  44. tempStack.add(splitArray[i]);
  45. }else {
  46. //说明是非符号,都添加进去
  47. resultList.add(splitArray[i]);
  48. }
  49. }
  50. //遍历完了,把临时stack里的东西都加到结果stack里去
  51. while (!tempStack.empty()){
  52. resultList.add(tempStack.pop());
  53. }
  54. return resultList;
  55. }
  1.  

Java使用BigDecimal精确计算的简单公式计算器的更多相关文章

  1. Java简单公式计算器

    最近给公司开发业务代码时,碰到一个场景,简单描述是这样的: 客户要向咱们公司定制一件产品,这个产品呢,有很多属性,那公司得根据这些属性报价呀,怎么报价呢?公司针对某种类型的产品有一个基准价,在同类产品 ...

  2. BigDecimal精确计算工具类

    前言 在实际开发中,遇到例如货币,统计等商业计算的时候,一般需要采用java.math.BigDecimal类来进行精确计算.而这类操作通常都是可预知的,也就是通用的.所以,写了个工具类来方便以后的工 ...

  3. java的数字精确计算问题-BigDecimal

    java的数字运算,偶尔会出现精度的问题,以下阐述的 java的BigDecimal类的使用. 例如: System.out.println(0.9+0.3); 结果1.2 System.out.pr ...

  4. [转] 商业应用中Java浮点数的精确计算及表示

    [From] https://blog.csdn.net/stevene/article/details/586089 问题提出 (1).浮点数精确计算 胜利油田三流合一项目中一直存在一个问题,就是每 ...

  5. BigDecimal精确计算及陷阱

    BigDecimal通常在涉及到精确计算的时候会用到,下面是自己多次错误使用BigDecimal的总结. 结论: BigDecimal初始化小数时,尽量用字符串形式,例如new BigDecimal( ...

  6. 运用BigDecimal精确计算

    package com.wzh.test; import java.math.BigDecimal; public class test { /** * @param args */ public s ...

  7. Java 根据年月日精确计算年龄

    import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * Created b ...

  8. Java浮点数float,bigdecimal和double精确计算的精度误差问题总结

    (转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...

  9. Java使用BigDecimal解决精确计算的问题

    最近有人在微信上给我发了一个数学题目,如下图: 我看了之后感觉很是简单,但是却想了半天才解出来.解出来后我想到了用程序再解一遍,然而精确计算的问题却让人头疼不已. 解题思路: 思路其实很简单,暴力求解 ...

随机推荐

  1. Final-阶段站立会议4

    组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 代码地址:HTTPS:https://git.coding.net/jx8zjs/llk.git SSH:git@git.coding.n ...

  2. JavaScript显示当前时间的代码

    方法一: <script type="text/javascript"> function startTime() { //获取当前系统日期 var today=new ...

  3. Objective-C基础语法快速入门

    Objective-C基础语法快速入门 2010-11-04 16:32 折酷吧 zheku8 字号:T | T 假如我们对面向对象的思维已经C语言都很熟悉的话,对于我们学习Objective-C将会 ...

  4. Jquery--防止冒泡

    e.stopPropagation();//阻止冒泡

  5. c语言的输入输出函数

    参考文章: http://blog.sina.com.cn/s/blog_784f40b80100psg9.html C语言输入输出函数分为两类: 1.格式化输入输出函数 2.非格式化输入输出 --- ...

  6. iTunes.exe 在win7系统中运行出错解决办法

    重新安装了iTunes打开后就报错,然后直接退出 查windows日志提示错误应用程序名称: iTunes.exe 错误模块名称: KERNELBASE.dll 重新安装iTunes问题依旧,后来在G ...

  7. jquery设置checkbox状态,设置dropdownlist选中值,隐藏某控件,给某控件追加东西

    jquery设置checkbox状态 $("[ID$=chkType]").attr("checked", true); jquery设置dropdownlis ...

  8. [转]Android View.onMeasure方法的理解

    转自:http://blog.sina.com.cn/s/blog_61fbf8d10100zzoy.html Android View.onMeasure方法的理解 View在屏幕上显示出来要先经过 ...

  9. DevExpress中的ASPxTreeView 递归显示checknodes并获得选中值

    aspx代码 <dx:ASPxTreeView ID="ASPxTreeView1" runat="server"> </dx:ASPxTre ...

  10. JQuery选择器转义说明

    JQuery选择器 JQuery选择器规则, 借用了css1-3的规则(css选择器规则), 因为css本身也需要一套规则来索引DOM元素, 进而进行样式渲染,例如div.blue 表示目标DOM为 ...